1


0

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

Qty = 1であるすべてのOrderItemの数を取得したい(結果3が期待される)。 これは私がクエリを書く方法だと思いますが、2(各Orderドキュメントに対して1)を返します:

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

Qty = 1であるすべてのOrderItemの数を見つけるためにクエリするにはどうすればよいですか?

4 Answer


4


このスレッドを読んでいる他の人に明確にするために。

OPのコマンド `db.orders.find({" OrderItems.Qty ":1})。count();`は、基本的に注文アイテムの数量が1であるドキュメントの数をカウントします。

ただし、OPは、数量が1であるすべてのOrderItemのカウントが必要です。 ここでの問題は、ドキュメントをカウントしていないことです。 Document内の配列内のアイテムをカウントしています。 したがって、javascriptと何らかの形の特別なreduce操作が必要です。


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


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


0


これにより、JavaScriptを使用せずにシェルで実行できるようになります(したがって、はるかに高速になります)。

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

残念ながら、これが一般的なクエリである場合、データはそのように構成されています。 「$ unwind」を実行するのは比較的高価です。 注文アイテムが、注文アイテムの配列を含むorderIDドキュメントではなく、注文IDでタグ付けされた個別のドキュメントとしてレイアウトされていないのは残念です…​つまり、あなたが持っているものの逆です。 それは処理がはるかに簡単で効率的です。