Запрос MongoDB отличается от вложенных документов

#node.js #mongodb #mongoose #aggregation-framework

#node.js #mongodb #mongoose #платформа агрегации

Вопрос:

Я использую Mongoose с NodeJS (typescript). Я пытаюсь суммировать количество для каждого местоположения. Пример вывода :

 [ 
 { name : "Bronx", count : 6 }, 
 { name : "Brooklyn", count : 6 }, 
 { name : "Manhattan", count : 6 }, 
 { name : "Queens", count : 6 } 
]
  

Текущая модель данных:

 data:
[
    {
        "news": {
            "_id": "5c7615a4ef5238a6c47cbcb9",
            "locations": [
                {
                    "_id": "5c7615a4ef5238a6c47cbcc6",
                    "id": "1",
                    "name": "Manhattan",                        
                    "children": [
                        {
                            "_id": "5c7615a4ef5238a6c47cbcc8",
                            "count": 3
                        },
                        {
                            "_id": "5c7615a4ef5238a6c47cbcc7",
                            "count": 2
                        }
                    ]
                }
            ]
        }
    },
    { 
     .... 
    }

]
  

Последний запрос, который я создал, был :

 DataModel.aggregate([
{ "$unwind": "$data.news.locations" },
{
    "$group": {
        "_id": "$data.news.locations",
        "count": { "$sum": "$$data.news.locations.zipcodes.count" }
    }
}]).exec(function(err, results){
    if (err) throw err;
        console.log(JSON.stringify(results, null, 4));

     }); 
  

Но я новичок в обработке запросов в MongoDB с помощью Mongoose, поэтому я действительно ценю любую помощь. Спасибо.

Комментарии:

1. Что вы пробовали и какую часть проблемы вы не понимаете? Ожидается, что вы предприняли некоторую попытку, а не просто ожидаете, что кто-то напишет весь код за вас. Пожалуйста, покажите свою попытку, и тогда кто-нибудь сможет помочь с неправильными частями.

2. @NeilLunn Вы правы, я только что отредактировал вопрос с моей последней попытки.

Ответ №1:

Вы были вроде как близки, всего несколько изменений:

 DataModel.aggregate([
  // Each array needs $unwind separately
  { "$unwind": "$data" },

  // And then down to the next one
  { "$unwind": "$data.news.locations" },

  // Group on the grouping key
  { "$group": {
    "_id": "$data.news.locations.name",
    "count": { "$sum": { "$sum": "$data.news.locations.children.count" } }
  }}
],(err,results) => {
   // remaining handling
})
  

Итак, поскольку у вас есть массивы внутри массива, и вы хотите перейти к "name" свойству внутри "locations" , вам нужно $unwind перейти к этому пункту. Вы должны $unwind использовать каждый уровень массива отдельно.

Технически по-прежнему существует children массив, но $sum его можно использовать для «суммирования массива значений», а также «накопления для ключа группировки». Отсюда $sum: { $sum утверждение внутри $group .

ВОЗВРАТ:

 { "_id" : "Manhattan", "count" : 5 }
  

Из деталей, приведенных в вопросе.