2017-12-13 9 views
0

embeddedManyという埋め込みドキュメントの配列を持つContainerという名前のコレクションがあります。埋め込まれた各ドキュメントは、Referencedという名前の他のいくつかのドキュメントを参照しています。これらの参照は、referenceManyという配列に格納されています。ドキュメントは次のようになります。ネストされた参照配列内の一致するサブドキュメント要素のみを返します

{ 
    "_id" : ObjectId("5a312337ea5cb32d30005d25"), 
    "embeddedMany" : [ 
     { 
      "referencedMany" : [ 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d24"), "myDb"), 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d23"), "myDb") 
      ] 
     }, 
     { 
      "referencedMany" : [ 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d23"), "myDb") 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
      ] 
     }, 
     { 
      "referencedMany" : [ 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d24"), "myDb") 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
      ] 
     } 
    ], 
} 

ここで特定のドキュメントを参照するすべての埋め込みドキュメントを見つける必要があります。これを言ってみましょう:DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb")

私はこのようにして、結果の文書を必要とする:

{ 
    "_id" : ObjectId("5a312337ea5cb32d30005d25"), 
    "embeddedMany" : [ 
     { 
      "referencedMany" : [ 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d23"), "myDb") 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
      ] 
     }, 
     { 
      "referencedMany" : [ 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d24"), "myDb") 
       DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
      ] 
     } 
    ], 
} 

私はthis非常に同様の問題をお読みください。だから、私は集約を使用し、埋め込まれたフィールドをフィルタリングする必要があると思います。私の集計はこれまでのようになります:

db.Container.aggregate(
    [ 
     { 
      $match: { 
       "embeddedMany.referencedMany.$id": ObjectId("5a312337ea5cb32d30005d22") 
      } 
     }, 
     { 
      $project: { 
       "embeddedMany": { 
        "$filter": { 
         "input": "$embeddedMany", 
         "as": "embedded", 
         "cond": { 
          "$eq": [ 
           "$$embedded.referencedMany.$id", 
           ObjectId("5a312337ea5cb32d30005d22") 
          ] 
         } 
        } 
       } 
      } 
     }, 
    ] 
); 

これは私が壁に当たった場所です。 MongoDBにはoutstanding bugがあり、の$eq表現を比較することができません。 $objectToArrayをハックとして使用することに関するいくつかの言及がありますが、私はそれを一から取り除くことができませんでした。

ご協力いただければ幸いです。

答えて

1

dbrefidの比較には、$projectステージを使用できます。

$objectToArray DBRefをキー値のペアに変換します。

次のステップは、idrefのキー値のペアのみを含むdbrefキーの値のペアです。$filterです。

次の手順は、id値のみを投影する$let + $mapの式です。

$in式を使用して、referencedMany id値に対してObjectId値で渡された値を比較することによって、最終的なステップは$filter "embeddedMany"になります。

{"$project":{"embeddedMany":{ 
    "$filter":{ 
    "input":"$embeddedMany", 
    "as":"embedded", 
    "cond":{ 
     "$in":[ 
     ObjectId("5a312337ea5cb32d30005d22"), 
     { 
      "$map":{ 
      "input":"$$embedded.referencedMany", 
      "as":"referenced", 
      "in":{ 
       "$arrayElemAt":[ 
       { 
        "$let":{ 
        "vars":{ 
         "id":{ 
         "$filter":{ 
          "input":{"$objectToArray":"$$referenced"}, 
          "as":"r", 
          "cond":{"$eq":["$$r.k",{"$literal":"$id"}]} 
         } 
         } 
        }, 
        "in":"$$id.v" 
        } 
       }, 
       0 
       ] 
      } 
      } 
     } 
     ] 
    } 
    } 
} 
}} 
+0

OMG、これは複雑で手伝ってくれてありがとうので、非常に多く、私はそれを理解することができます前に、それを詳細に調べる必要があります –

+0

。。。私の謝罪。私は不必要に複雑にしました。 – Veeram

1

あなたが望む結果があなたが与えた例のようなものであれば、オブジェクトを分解する必要もなく、参照したバグも心配する必要はありません。単にあなたのパイプラインでDBRefオブジェクト間の比較を使用(mongoシェルで実行例:

mydbref = DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb"); 
db.dbref.aggregate([ 
    {$match:{"embeddedMany.referencedMany":mydbref}}, 
    {"$project":{"embeddedMany":{ 
    "$filter":{ 
     "input":"$embeddedMany", 
     "cond":{ 
      "$in":[{$literal:mydbref},"$$this.referencedMany"] 
     } 
    } 
    }}} 
]) 
{ 
"_id" : ObjectId("5a312337ea5cb32d30005d25"), 
"embeddedMany" : [ 
    { 
     "referencedMany" : [ 
      DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d23"), "myDb"), 
      DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
     ] 
    }, 
    { 
     "referencedMany" : [ 
      DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d24"), "myDb"), 
      DBRef("Referenced", ObjectId("5a312337ea5cb32d30005d22"), "myDb") 
     ] 
    } 
] 
} 
関連する問題