MongoDB: получить количество массивов - PullRequest
1 голос
/ 03 июля 2010

С учетом этих документов:

db.orders.insert( {OrderId:1, OrderItems: [{OrderItemId:1, Qty:1}, {OrderItemId:2, Qty:1} ]} );
db.orders.insert( {OrderId:2, OrderItems: [{OrderItemId:1, Qty:1}, {OrderItemId:2, Qty:2} ]} );

Я бы хотел получить количество всех OrderItems, где Qty = 1 (ожидаемый результат 3). Вот как я думаю написать запрос, но он возвращает 2 (1 для каждого документа заказа):

db.orders.find({"OrderItems.Qty":1}).count();

Как я могу запросить, чтобы найти количество всех OrderItems, где Qty = 1?

Ответы [ 4 ]

4 голосов
/ 03 июля 2010

Просто чтобы быть понятным другим, читающим эту ветку.

Команда ОП db.orders.find({"OrderItems.Qty":1}).count();, в основном, подсчитывает количество документов, в которых количество единиц заказа составляет 1.

Однако OP хочет подсчитать все OrderItems, где количество равно единице. Проблема в том, что мы не считаем документы. Мы считаем элементы в массиве в документе. Отсюда необходимость в javascript и некоторой форме специальной операции сокращения.

2 голосов
/ 03 июля 2010

Вы можете использовать JavaScript:

db.orders.group(
{
  key: null, 
  cond: {'OrderItems.Qty':1}, 
  initial: {count: 0}, 
  reduce: function(el, running)
  {                                                                                                       
    running.count += el.OrderItems.filter(function(el)                                                    
    {                                                                                                     
      return el.Qty == 1;                                                                                 
    }).length;                                                                                            
  }                                                                                                       
});
0 голосов
/ 07 апреля 2013

Это должно сделать это для вас в оболочке без JavaScript (так что это будет намного быстрее);

db.orders.aggregate([
  {$unwind:'$OrderItems'},
  {$match: {'OrderItems.Qty':1}},
  {$group : { 
      _id : "Qty1",
      sum: {$sum:1}
  }}
]);

Хотя, к сожалению, ваши данные структурированы так, если это обычный запрос.Необходимость сделать $unwind относительно дорога.Жаль, что ваши заказы не выложены в виде отдельных документов, помеченных идентификатором заказа, а не в документах orderID, содержащих массивы позиций заказа ... другими словами, в противоположность тому, что у вас есть.Это было бы намного проще и эффективнее обрабатывать.

0 голосов
/ 07 апреля 2013
db.orders.aggregate([
  {$unwind: '@OrderItems'},
  {$match : {'OrderItems.Qty':1}},
  {$group : { _id : null, 'countOfQty1':{$sum:'$OrderItems.Qty'} }}
]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...