2014-09-18 4 views
0

ObjectOds, someOtherArray 배열이 있고 집계 쿼리의 현재 objectId와 비교해야합니다. 나는 대부분의 쿼리가 끝났다고 믿지만 현재의 objectId가 someOtherArray 배열에 있는지 확인하는 방법을 모르겠습니다. 아래 코드에서 내가 갇혀있는 부분에 대해 의견을 말합니다.MongoDB 집계 쿼리 : 값이 배열에 있는지 확인하십시오.

db.Collection.aggregate([ 
{ 
    $project: { 
     aField : { 
      $map : { 
       input: "$anArray", 
       as : "arrayValue", 
       //this is where I'm not sure on what to do. I need something to return 
       //true or false on whether that item is in someOtherArray 
       in: { $cond : {if: { $isInArray: [ $$arrayValue, someOtherArray] }, then: arrayValue, else: '' }} 
      } 
     } 
    } 
} 
]); 

답변

1

여기 당신의 전반적인 목적은 당신이 바로 그때 한 배열의 내용은 (문서 또는 다른 배열 필드) 다른 공급 배열의 내용과 일치하는 경우 테스트하려는 경우 확실하지,하지만 기본적으로 당신이 할 수있는 다만 $setIntersection 연산자이를 테스트 : $setIntersection에서 리턴 어떤

db.Collection.aggregate([ 
    { "$project": { 
     "present": { "$gt": [ 
      { "$size": { "$setIntersection": [ "$anArray", someOtherArray ] } }, 
      0 
     ]} 
    }} 
]) 

의 "동일한"단지 요소이고, "설정"이므로 중복 제거한다. 어쩌면 그게 무엇이든지 있는지 알아보기 위해 결과에 대해 $size 테스트를하지 않고도 자신이 원하는 것일지도 모릅니다.

요소가 비교 배열에서 무언가와 일치하는 원본 위치의 원본에서 반환되는 일종의 "일치 마스크"를 찾은 경우 $map을 사용하여 두 배열을 서로 비교할 수 있습니다 각 동작 :

db.Collection.aggregate([ 
    { "$project": { 
     "altered": { 
      "$map": { 
       "input": "$anArray", 
       "as": "orig", 
       "in": { 
        "$cond": [ 
         { "$anyElementTrue": { 
          "$map": { 
           "input": anotherArray 
           "as": "compare", 
           "in": { "$eq": [ "$$orig", "$$compare" ] } 
          } 
         }}, 
         "$$orig", 
         false 
        ] 
       } 
      } 
     } 
    }} 
]) 

그리고이 문서 만 원래 위치에서 "일치"요소로 표현 false 모든 다른 요소와 원본과 동일한 길이의 배열을 반환 할 것이다. 따라서 여기서 "진리"테스트는 배열의 각 요소에 의해 비교되고, $anyElementTrue을 사용하여 단일 결과로 증류됩니다.

이러한 작업은 모두 "사실"개념에 따라 작동하거나 그렇지 않으면 결과의 "조합"을 결정하는 수단입니다. 그러므로 결과에 false 결과가 나오지 않는다면 먼저 일치하지 않는 문서를 제거하기 위해 먼저 필터링해야합니다. 이 쿼리에 대한 단지 $in 연산자 : 여기

db.Collection.aggregate([ 
    { "$match": { 
     "anArray": { "$in": someOtherArray } 
    }} 
]) 

모든 가정이 someOtherArray 그냥있는 그것을 것, 여기에 BSON 표현으로 "보간"것입니다 외부에서 선언 된 변수는 점이다. 문서의 다른 필드를 사용하는 경우 모든 경우에 "$someOtherArray"으로 표기 할 수 있습니다. 물론 필드를 비교할 수없는 $match 파이프 라인을 제외하고는 $project을 "필터링"하기 전에 해당 평가의 "진실성"이 필요합니다. 그 결과에.

+0

어쨌든 $ setIntersection에서 성능을 향상시킬 수 있습니까? 이 쿼리는 오랜 시간이 걸립니다. 이 경기를하기 전에 경기를 풀고 다시 경기를 펼치면 빠를 것으로 보이지만 잘못된 결과가 나옵니다. {$ unwind : "anArray"}, { "$ match": {{{$ $ {{{{{{{$ $}} ') {dbstats} {dbstats} {dbstats} {dbstats} {dbstats} "anArray":}} –

+0

@raging_subs 가장 좋은 방법은 파이프 라인에서 결과를 제한하는 것입니다. 여기에서하는 모든 일이나 최종 목적이 노출되지 않았습니다. 그래서 이것은 논평하기가 매우 어렵습니다. 그래서 먼저 일치하고, 프로젝트를 찾은 다음 다시 일치하여 결과를 필터링하십시오. –

+0

일치하는 모든 점을 얻은 후에는 레벨을 올라가서 setIntersection 내에서 내 ID와 일치하는 객체의 필드를 가져올 수 있습니까? ie) db.Collection.골재 ([ { "$ 프로젝트"{ "본"{ { "$의 setIntersection"[ "$이 anArray"someOtherArray]}} "someField". "$ UpAnObject.field" }} ]) note upAnObject를 말할 때 {upAnObject : {field : value, $ anArrayComparison : {fieldToMatchSomeOtherArray : value}}}를 의미합니다. –

관련 문제