2016-11-24 6 views
2

サブ文書内の配列のアイテムの特定のフィールドのみを投影するにはどうすればよいですか?サブ文書内の配列項目の一部のフィールドのみを投影する

は、以下の(単純化)の例考えてみましょう:集約した後

{ 
    "_id" : ObjectId("573d70df080cc2cbe8bf3222"), 
    "name" : "Nissan", 
    "models" : [ 
     { 
      "name" : "Altima", 
      "body" : { 
       "type" : 2, 
       "maxprice" : 31800.00, 
       "minprice" : 21500.00 
      } 
     }, 
     { 
      "name" : "Maxima", 
      "body" : { 
       "type" : 2, 
       "maxprice" : 39200.00, 
       "minprice" : 28800.00 
      } 
     } 
    ] 
}, 
{ 
    "_id" : ObjectId("80cc2cbe8bf3222573d70df0"), 
    "name" : "Honda", 
    "models" : [ 
     { 
      "name" : "Accord", 
      "body" : { 
       "type" : 2, 
       "maxprice" : 34100.00, 
       "minprice" : 20400.00 
      } 
     }, 
     { 
      "name" : "Civic", 
      "body" : { 
       "type" : 3, 
       "maxprice" : 27900.00, 
       "minprice" : 19800.00 
      } 
     } 
    ] 
} 

を、私は次の出力を取得したいのですが:

{ 
    "_id" : ObjectId("573d70df080cc2cbe8bf3222"), 
    "name" : "Nissan", 
    "models" : [ 
     { 
      "type" : 2, 
      "minprice" : 21500.00 
     }, 
     { 
      "type" : 2, 
      "minprice" : 28800.00 
     } 
    ] 
}, 
{ 
    "_id" : ObjectId("80cc2cbe8bf3222573d70df0"), 
    "name" : "Honda", 
    "models" : [ 
     { 
      "type" : 2, 
      "minprice" : 20400.00 
     }, 
     { 
      "type" : 3, 
      "minprice" : 19800.00 
     } 
    ] 
} 

だから、基本的にすべての文書、文書のすべてのフィールドを取得しますmodelsの配列のすべての項目が、配列項目の一部のフィールドだけがmodelsにあります。助けてください。

答えて

1

$map演算子を使用して "models"フィールドを$projectにする必要があります。

db.collection.aggregate([ 
    { "$project": { 
     "name": 1, 
     "models": { 
      "$map": { 
       "input": "$models", 
       "as": "m", 
       "in": { 
        "type": "$$m.body.type", 
        "minprice": "$$m.body.minprice" 
       } 
      } 
     } 
    }} 
]) 
+0

これは素晴らしいです! – Alex

-1

$unwindあなたは基本的にあなたが欲しい(非ネストされた)フィールドをフィルタリングすることができますあなたの友人

ファーストです。お使いのモデルの

var projection = {$project:{name:'$name', models:'$models'}}; 
db.dum.aggregate(projection) 

foreachのは、あなたのアイデアは、あなたのモデルのフィールドから発行されたすべての文書は、_idフィールドを経由して、後に再編成されることがある文書

var unwindModels = {$unwind:{'$models'}} 
db.dum.aggregate(projection, unwindModels) 

を発行します。

のforeach文書、あなただけの、あなたが(元のレコードを追跡し、各レコードの_idのおかげで)

var aggregateModels = {$group:{_id:'$_id', name:{$last:'$name'}, models:{$push:{type:'$type', minprice:'$minprice'}}}} 
db.dum.aggregate(projection, unwindModels, keepSubFields, aggregateModels) 
配列としてモデルを再集計後
var keepSubFields = {$project:{name:'$name', type:'$models.body.type', minprice:'$models.body.minprice'}} 
db.dum.aggregate(projection, unwindModels, keepSubFields) 

をしたいフィールド(サブ)を保ちます

note1:私たちのプライマリキーが_idではなく、< _id、name>のため$ lastを使用できます。あなたはaggregateModelsステージにコレクションを反復処理するとき、あなたのレコードは、フォームの < _id、名前、タイプ、minprice>

あるので、我々は、$の種類によってタイプを参照してください。

注2($最初あまりにも良いでしょう)

関連する問題