简体   繁体   English

MongoDB:获取数组计数

[英]MongoDB: Get count of Array

Given these documents: 鉴于这些文件:

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

I'd like to get the count of all OrderItems where the Qty = 1 (expected result 3). 我想获取数量= 1(预期结果3)的所有OrderItems的计数。 This is how I think to write the query, but it returns 2 (1 for each Order document): 我就是这样写查询的,但是它返回2(每个Order文档为1):

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

How can I query to find the count of all OrderItems where the Qty = 1? 如何查询以找到数量= 1的所有OrderItem的计数?

Just to be clear for others reading this thread. 只是为了让其他阅读此线程的人清楚。

The OP's command db.orders.find({"OrderItems.Qty":1}).count(); OP的命令db.orders.find({"OrderItems.Qty":1}).count(); basically counts the number of Documents where any order item has a quantity of 1. 基本上是计算任何订购项目的数量为1的单据数量。

However, the OP wants a count of all OrderItems where the quantity is one. 但是,OP希望对数量为1的所有OrderItem进行计数。 The problem here is that we're not counting Documents. 这里的问题是我们没有计算文档。 We're counting items within an array within a Document. 我们正在计算文档中数组中的项目。 Hence the need for javascript and some form of special reduce operation. 因此需要javascript和某种形式的特殊reduce操作。

You could use JavaScript: 您可以使用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;                                                                                            
  }                                                                                                       
});
db.orders.aggregate([
  {$unwind: '@OrderItems'},
  {$match : {'OrderItems.Qty':1}},
  {$group : { _id : null, 'countOfQty1':{$sum:'$OrderItems.Qty'} }}
]);

This should do it for you in the shell without JavaScript (so it'll be a lot quicker); 这应该在没有JavaScript的shell中为您完成(这样会更快);

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

Although it's unfortunate your data is structured like that if this is a common query. 虽然很遗憾,但是如果这是常见查询,则数据的结构是这样的。 Having to do an $unwind is relatively expensive. 必须进行$unwind相对昂贵。 It's a shame your order items aren't laid out as separate documents tagged with the order ID instead of orderID documents containing arrays of order items...in other words, the reverse of what you have. 遗憾的是,您的订单项没有作为带有订单ID标记的单独文档而不是包含订单项数组的orderID文档进行布局……换句话说,就是您所拥有的相反。 That would be much easier and more efficient to process. 这将更容易且更有效地处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM