2017-08-21 6 views
2

私は照会しているデータセットを持っています。データは次のようになります。ユニークな項目を配列から結合する

db.activity.insert(
    { 
     "_id" : ObjectId("5908e64e3b03ca372dc945d5"), 
     "startDate" : ISODate("2017-05-06T00:00:00Z"), 
     "details" : [ 
      { 
       "code" : "2", 
       "_id" : ObjectId("5908ebf96ae5003a4471c9b2"), 
       "walkDistance" : "03", 
       "jogDistance" : "01", 
       "runDistance" : "08", 
       "sprintDistance" : "01" 
      } 
     ] 
    } 
) 

db.activity.insert(
    { 
     "_id" : ObjectId("58f79163bebac50d5b2ae760"), 
     "startDate" : ISODate("2017-05-07T00:00:00Z"), 
     "details" : [ 
      { 
       "code" : "2", 
       "_id" : ObjectId("58f7948fbebac50d5b2ae7f2"), 
       "walkDistance" : "01", 
       "jogDistance" : "02", 
       "runDistance" : "09", 
       "sprintDistance" : "" 
      } 
     ] 
    } 
) 

マイ所望の出力などになります、しかし

db.activity.aggregate([ 
    { 
     $facet: { 
      "walk": [ 
       {$unwind: '$details'}, 
       {$group: {_id: null, uniqueValues: {$addToSet: "$details.walkDistance"}}} 
      ], "jog": [ 
       {$unwind: '$details'}, 
       {$group: {_id: null, uniqueValues: {$addToSet: "$details.jogDistance"}}} 
      ], "run": [ 
       {$unwind: '$details'}, 
       {$group: {_id: null, uniqueValues: {$addToSet: "$details.runDistance"}}} 
      ], "sprint": [ 
       {$unwind: '$details'}, 
       {$group: {_id: null, uniqueValues: {$addToSet: "$details.sprintDistance"}}} 
      ] 
     } 
    }]) 

:そのためには

[ 
    { 
    "_id": null, 
    "uniqueValues": [ 
     "03", 
     "01", 
     "08", 
     "02", 
     "09" 
    ] 
    } 
] 

、私は次のコードを開発しました私はまだ自分の_id: nulluniqueValuesの配列で4つのファセットを取得しています。それらをすべて1つの配列に含めるようにクエリを変更するにはどうすればいいですか?""も除外されます。

答えて

1

$facet実際にはここで使用するのが最良ではありません。あなたは本当にただ$concatArraysを適用し、$setDifference$filterで結果をダウンフィルタリングする必要があります。

/* 1 */ 
{ 
    "_id" : null, 
    "uniqueArray" : [ 
     "09", 
     "03", 
     "01", 
     "02", 
     "08" 
    ] 
} 

ので$concatArraysを使用して単一のアレイにすべての配列値をもたらした後、あなた:

db.activity.aggregate([ 
    { "$project": { 
    "_id": 0, 
    "unique": { 
     "$filter": { 
     "input": { 
      "$setDifference": [ 
      { "$concatArrays": [ 
       "$details.walkDistance", 
       "$details.jogDistance", 
       "$details.runDistance", 
       "$details.sprintDistance" 
      ]}, 
      [] 
      ] 
     }, 
     "cond": { "$ne": [ "$$this", "" ] } 
     } 
    } 
    }}, 
    { "$unwind": "$unique" }, 
    { "$group": { 
    "_id": null, 
    "uniqueArray": { "$addToSet": "$unique" } 
    }} 
]) 

は結果を返します。 $setDifferenceを適用してリストを「一意の」値に減らします。 $filterは、望ましくない値の""を削除します。

$unwindを単数形と縮小形のリストに適用して$groupに戻して$addToSetに戻すだけで、文書間で一意の値を保持することができます。

また、単に$concatArraysのみ、その後$unwind$matchが、他の事業者には、本当に多くの費用とあなたが$unwindに到達する前に、既に文書内の「ユニーク」に絞り込むことで、負荷の一部を軽減しませんでした。だから、そうするのが良い。

本当に私たちはやっぱ「セット」について話しているので、これも単に$setUnion$setDifference、futherを分けることができます。

db.activity.aggregate([ 
    { "$project": { 
    "_id": 0, 
    "unique": { 
     "$setDifference": [ 
     { "$setUnion": [ 
      "$details.walkDistance", 
      "$details.jogDistance", 
      "$details.runDistance", 
      "$details.sprintDistance" 
     ]}, 
     [""] 
     ] 
    } 
    }}, 
    { "$unwind": "$unique" }, 
    { "$group": { 
    "_id": null, 
    "uniqueArray": { "$addToSet": "$unique" } 
    }} 
]) 

をそして、それが全体的な文がバックにMongoDB 2.6の互換性になることを意味し、または

"$setDifference": [ 
    { "$setUnion": [ 
     { "$map": { "input": "$details", "as": "d", "in": "$$d.walkDistance" } }, 
     { "$map": { "input": "$details", "as": "d", "in": "$$d.jogDistance" } }, 
     { "$map": { "input": "$details", "as": "d", "in": "$$d.runDistance" } }, 
     { "$map": { "input": "$details", "as": "d", "in": "$$d.sprintDistance" } } 
    ]}, 
    [""] 
    ] 

$facet原因を実行している一方で:など$details.walkDistanceなど、すべてのフォームが$mapを使用して長い形式で書き出された場合だろうアレイ内のすべてのプロパティのコレクション全体を「ブルートフォース」で解析し、そのパスのそれぞれで処理されるのは$unwindです。だから結果を得るのに本当に非効率な方法です。そうしないでください。

+0

私はこの答えに直接関係する別の質問、特に '$ match'文の追加について投稿します。単純に答えの先頭に追加するだけで動作しません。 –

+0

https://stackoverflow.com/questions/45809451/add-match-statement-to-query-containing-concatarrays –

関連する問題