2014-09-18 80 views
0

我有一個ObjectIds,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運營商測試:

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

$setIntersection返回什麼就是這樣的「相同」的元素和作爲「設置」,以便消除重複。也許這就是你自己想要的,而不是對結果進行$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管道的例外情況不能與字段進行比較,並且需要您在「過濾」之前評估該評估的「真實性」在那個結果。

+0

有沒有辦法提高$ setIntersection的性能?這個查詢需要很長時間。在此之前,我正在進行一場比賽,然後放鬆並再次比賽,看起來更快,但返回一些錯誤的結果。即:db.Collection.aggregate {「$ match」{{$ unwind:「anArray」},{「$ match」:{「$ match」:{「$ in」:someOtherArray} {「$ in」:someOtherArray} 「anArray」:{「$ in」:someOtherArray} }}, ]) – 2014-09-19 04:44:18

+0

@raging_subs最好的方法是限制管道中的結果,這就是我首先提到過濾的原因。你沒有暴露你在這裏做的一切或你的最終目的是什麼。所以這很難評論。因此,先匹配項目,然後再次匹配篩選結果 – 2014-09-19 04:48:45

+0

當我得到所有匹配的點後,是否有可能上升到一個級別來獲取匹配我的id在setIntersection內的對象的字段?即) db.Collection。集合體([{ 「$項目」:{ 「存在」:{{ 「$ setIntersection」:[ 「$ anArray」,someOtherArray]}} 「someField」: 「$ UpAnObject.field」 }} ]) 請注意,當我說upAnObject的意思是{upAnObject:{field:value,$ anArrayComparison:{fieldToMatchSomeOtherArray:value}}} – 2014-09-19 13:29:13