2017-04-23 4 views
0

私はMongodbとNoSQLには新しく、mongodbs集約関数を使用して、あるコレクションのデータを集約して別のコレクションに挿入しようとしています。

オリジナルコレクション { supplier: 'aldi', timestamp: '1492807458', user: '[email protected]', hasBeenAggregated:false, items:[{ name: 'butter', supplier: 'aldi', expiry: '1492807458', amount: 454, measureSymbol: 'g', cost: 2.19 },{ name: 'milk', supplier: 'aldi', expiry: '1492807458', amount: 2000, measureSymbol: 'ml', cost: 1.49 }] }

私が達成しようとしている出力例は次のようになります:

新コレクション { user:'[email protected]', amount: 3.68, isIncome: false, title: 'food_shopping', timestamp: '1492807458' }

元のコレクションの例は、このことだろう

私が使用している集約関数は次のとおりです。

集約 var result = db.runCommand({ aggregate: 'food_transactions', pipeline: [ {$match: {hasBeenAggregated: false}}, {$unwind: '$items'}, {$group:{_id: '$_id',amount:{$sum: '$items.cost'}}}, {$project: { _id:0, user:1, amount:1, isIncome: {$literal: false}, title:{$literal: 'food_shopping'}, timestamp:1 }} ] }); printjson(result)

この集計関数はuserまたはtimestampフィールドを返しません。私はグループに結果をしませんし、$project段階で計算を行う場合は、フィールドがすべて正しく

出力 { "amount" : 3.6799999999999997, "isIncome" : false, "title" : "food_shopping" }

投影されているが、明らかに、そこにある:代わりに、私は次の出力を得ますitemsアレイ内の各サブ文書に対して作成された新しい文書であり、集約の目的をむしろ無効にする。

私は間違っていますか?

答えて

2

$groupパイプラインを更新して、パイプラインのさらに下方に投影したいすべてのフィールドを含めます。

はあなたが3.4バージョンである場合は、以下にあなたの凝集を簡素化することができ、さらに $first

{$group:{_id: '$_id', user:{$first:'$user`}, amount:{$sum: '$items.cost'}}}, 

を使用することができ、ユーザのフィールドを含めます。

を使用して、すべてのitemのコストを1つの文書で合計します。すべての文書について、$group$reduceの後に追加することができます。

db.collection.aggregate([ 
     {$match: {hasBeenAggregated: false}}, 
     {$project: { 
      _id:0, 
      user:1, 
      amount: { 
       $reduce: { 
       input: "$items", 
       initialValue: 0, 
       in: { $add : ["$$value", "$$this.cost"] } 
       } 
      }, 
      isIncome: {$literal: false}, 
      title:{$literal: 'food_shopping'}, 
      timestamp:1 
     }} 
    ]) 
関連する問題