私はmongodbアグリゲーションクエリを使用して2つのコレクションに結合し、結合された配列のすべての一意の値を区別しています。 *注:私は必ずしも、どのフィールド(キー)がmetaDataMap配列にあるのかわかりません。そして、私はマップに存在していてもいなくてもよいフィールドを数えたり含める必要はありません。そのため、集約クエリは、そうであるように見えます。Mongodbアグリゲーションパイプラインのサイズと速度の問題
だから私の2つのコレクションは、次のようになります。
:イベントを紹介{
"_id" : "1",
"name" : "event1",
"objectsIds" : [ "1", "2", "3" ],
}
オブジェクト
{
"_id" : "1",
"name" : "object1",
"metaDataMap" : {
"SOURCE" : ["ABC", "DEF"],
"DESTINATION" : ["XYZ", "PDQ"],
"TYPE" : []
}
},
{
"_id" : "2",
"name" : "object2",
"metaDataMap" : {
"SOURCE" : ["RST", "LNE"],
"TYPE" : ["text"]
}
},
{
"_id" : "3",
"name" : "object3",
"metaDataMap" : {
"SOURCE" : ["NOP"],
"DESTINATION" : ["PHI", "NYC"],
"TYPE" : ["video"]
}
}
私の結果は、私がこれまででてきた何
{
_id:"SOURCE", count:5
_id:"DESTINATION", count: 4
_id:"TYPE", count: 2
}
です
db.events.aggregate([
{$match: {"_id" : id}}
,{$lookup: {"from" : "objects",
"localField" : "objectsIds",
"foreignField" : "_id",
"as" : "objectResults"}}
,{$unwind: "$objectResults"} //Line 1
,{$project: {x: "$objectResults.metaDataMap"}} //Line 2
,{$unwind: "$x"}
,{$project: {"_id":0}}
,{$project: {x: {$objectToArray: "$x"}}}
,{$unwind: "$x"}
,{$group: {_id: "$x.k", tmp: {$push: "$x.v"}}}
,{$addFields: {tmp: {$reduce:{
input: "$tmp",
initialValue:[],
in:{$concatArrays: [ "$$value", "$$this"]}
}}
}}
,{$unwind: "$tmp"}
,{$group: {_id: "$_id", uniqueVals: {$addToSet: "$tmp"}}}
,{$addFields: {count: {"$size":"$uniqueVals"}}}
,{$project: {_id: "$_id", count: "$count"}}
]);
私の問題は、私が行1にマークしたことです。& 2.上記は動作しますが、metaDataMap配列フィールド(objectsResults.metaDataMap)で25,000の値に約50秒かかります。たとえば、オブジェクト1のmetaDataMap SOURCE配列に25,000の値があるとします。それは遅くする方法です。これは(3秒未満)の方法より高速であるだけ〜万個のアイテム以下を持っているデータセット上で実行することができます
,{$project: {x: "$objectResults.metaDataMap"}} //Line 1
,{$unwind: "$x"} //Line 2
:それを行うには私の他のより高速な方法はとライン1 & 2を交換しました。それ以上の高さで、「最大ドキュメントサイズを超えています」というエラーが表示されます。
助けてください!
「さまざまな配列の25,000個のアイテム」の説明をもう少し追加できますか? –
ちょっと考えました。あなたの 'metaDataMap'構造体を' 'metaDataMap ':[" k ":{" SOURCE "、" v ":[" ABC "、" DEF "]} ...]'に変更して、 '$ lookup'の後の' $ map'ステージです。 "{" $ map ":{" $ map ":{" $ map ":" $ " "$" resultim.k "、" v ":{\t" $ size ":\t" $ "resultom"、 "as" $ resultim.v "}}}}}}}}}'となります。私はあなたがサイズを得ることができるこの方法を信じて、巻き戻しは速くなければなりません。 – Veeram
しかし、私はサイズとは別のカウントを取得しません。私は?私はv値を重複する必要があります。 – Deckard