2017-01-15 19 views
1

現在スキーマを変更していますが、アグリゲーションフレームワークとbulkWriteを使用して比較的簡単な変換を行う必要があります。配列をオブジェクトの配列にカプセル化/変換する

私はこの配列を取ることができるようにしたい:

​​

このスロークエリ:元の値がカプセル化されている類似した配列への

{ 
    ..., 
    "images" : [ 
     "http://example.com/...", 
     "http://example.com/...", 
     "http://example.com/..." 
    ] 
} 

と集計しかし、それはコレクション全体を巻き戻すにはばかげて高価です。

[ 
    { 
     $match: {} 
    }, 
    { 
     $unwind: { 
      path : "$images", 
     } 
    }, 
    { 
     $group: { 
      _id: "$_id", 
      images_2: {$addToSet: {url: "$images"}} 
     } 
    }, 
] 

これはどのようにprojectまたは他のいくつかの安価な凝集に達成することができますか?仕事をする必要があります

答えて

2

$map式は、これを試してみてください。

db.col.aggregate([ 
    { 
    $project: { 
     images: { 
     $map: { 
      input: '$images', 
      as: 'url', 
      in: { 
      url: '$$url' 
      } 
     } 
     } 
    } 
    } 
]); 
1

あなたはこのためbulkWrite()メソッドを使用する必要はありません。

アグリゲーションアレイ演算子$mapを使用すると、配列内の各要素要素に式を適用できます。

ここでは、式は値が配列内の項目である新しいオブジェクトを作成するだけです。

let mapExpr = { 
    "$map": { 
     "input": "$images", 
     "as": "imageUrl", 
     "in": { "url": "$$imageUrl } 
    } 
}; 

最後にあなたのコレクションを上書きするか、別のコレクションに結果を書き込むこと$out集約パイプライン演算子を使用することができます。

もちろん、$mapは集約パイプライン演算子ではないため、$map式はパイプラインステージで使用する必要があります。

これは、MongoDBのバージョンによって異なります。

MongoDB 3.4では$addFieldsを使用して、文書内の「画像」フィールドの値を変更するのが最善の方法です。 MongoDBの3.2から

db.collection.aggregate([ 
    { "$addFields": { "images": mapExpr }}, 
    { "$out": "collection } 
]) 

後方には、$projectパイプラインステージを使用する必要がありますが、また

db.collection.aggregate([ 
    { "$project": { "images": mapExpr } }, 
    { "$out": "collection } 
]) 
ドキュメントに手動で他のすべてのフィールドを含める必要が
関連する問題