2010-07-02 45 views
1

的计数这些文件:MongoDB的:获取给定数组

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} ]}); 

我想获得在数量= 1(预期结果3)所有的OrderItems的计数。这是我觉得写的查询,但它返回2(1为每个订单文档):

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

我如何可以查询到找到所有的OrderItems在数量= 1的计数?

回答

2

您可以使用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

你能帮我解决在Mongo shell中使用的语法吗? (mongo.exe) – whitez 2010-07-03 01:01:17

+0

@whitez,我为此更新了它。 – 2010-07-03 01:16:44

4

只是要清楚别人阅读此线程。

的OP的命令db.orders.find({"OrderItems.Qty":1}).count();基本上计数其中任何订单项目有1

数量然而,OP希望所有的OrderItems其中数量是一个计数文件的数量。这里的问题是我们不计算文档。我们正在计算文档中数组内的项目。因此需要javascript和某种形式的特殊的reduce操作。

+0

这是更多的评论或回答?我不理解它是一个答案,但这可能是因为我不熟悉代码,但我相信这个答案被标记为原因 – Huangism 2015-01-22 19:05:07

+0

不,这显然不是一个答案,而是对这个问题和其他答案的评论。 SO上没有“线程”,只是问题和答案。这应该是对这个问题的评论。 – Cimbali 2015-01-22 20:49:17

0
db.orders.aggregate([ 
    {$unwind: '@OrderItems'}, 
    {$match : {'OrderItems.Qty':1}}, 
    {$group : { _id : null, 'countOfQty1':{$sum:'$OrderItems.Qty'} }} 
]); 
+0

我认为这是不对的。有很多错别字。 – cirrus 2013-04-06 23:12:07

+0

现在是社区wiki。如果你认为这是不对的,你可以适当地改变它。 – 2013-04-07 09:26:00

0

这应该在没有JavaScript的shell中这样做(所以它会更快);

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

虽然不幸的是,如果这是一个常见的查询,那么您的数据的结构就像这样。必须做$unwind是相对昂贵的。令人遗憾的是,您的订单商品不是作为用订单ID标记的单独文档布置的,而是包含包含订单商品数组的订单ID文档......换句话说,与您所拥有的相反。处理起来会更容易,更有效率。