2017-12-13 7 views
0

embeddedMany라는 포함 된 문서 배열이있는 컨테이너라는 이름의 컬렉션이 있습니다. 각 임베디드 문서는 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 매우 비슷한 문제를 참조하십시오. 그래서 집계를 사용하고 embeddedMany 필드를 필터링해야한다고 생각합니다. 내 집계는 지금까지 이렇게 보입니다.

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 표현에서 $id을 비교할 수 없습니다. $objectToArray을 해킹으로 사용하는 것에 대한 언급이 있지만 모두 정리할 수는 없습니다.

도움을 주시면 감사하겠습니다.

답변

1

dbrefid 비교를 위해 $project 단계를 사용할 수 있습니다.

$objectToArray DBRef를 키 값 쌍으로 변환합니다.

다음 단계는 id 키 값 쌍만 포함하는 dbref 키 값 쌍 $filter입니다.

다음 단계는 + $map id 값을 투영하는 표현식입니다.

마지막 단계는 $in 표현식을 사용하여 referencedMany id 값과 비교하여 ObjectId 값으로 전달 된 값을 비교하여 "embeddedMany"배열에 $filter입니다.

{"$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") 
     ] 
    } 
] 
}