你所要求的不是一個「查詢」,而是基本上只是從每個文檔中的數組中過濾內容。
爲此,您可以.aggregate()
和$project
:
db.survey.aggregate([
{ "$project": {
"results": {
"$setDifference": [
{ "$map": {
"input": "$results",
"as": "el",
"in": {
"$cond": [
{ "$and": [
{ "$eq": [ "$$el.product", "xyz" ] },
{ "$gte": [ "$$el.score", 6 ] }
]}
]
}
}},
[false]
]
}
}}
])
因此,而不是「contrain」結果有一個數組成員匹配,這一切都是在做條件文件被「過濾」陣列成員指出,不符合條件,但如果需要的話,返回帶有空數組的文檔。
目前最快的方法是用$map
檢查所有元素,並且$setDifference
過濾掉從該檢查返回的任何值false
。可能的缺點是「集合」必須包含獨特的元素,所以只要元素本身是唯一的就可以了。
未來版本將具有$filter
方法,其類似於在結構$map
,而是直接刪除不匹配的結果,其中如$map
只是返回它們(通過$cond
,要麼匹配元件或false
)並且隨後更適合。
否則,如果不是唯一的或者MongoDB服務器版本低於2.6,你這樣做是使用$unwind
,在非性能方法:
db.survey.aggregate([
{ "$unwind": "$results" },
{ "$group": {
"_id": "$_id",
"results": { "$push": "$results" },
"matched": {
"$sum": {
"$cond": [
{ "$and": [
{ "$eq": [ "$results.product", "xyz" ] },
{ "$gte": [ "$results.score", 6 ] }
]},
1,
0
]
}
}
}},
{ "$unwind": "$results" },
{ "$match": {
"$or": [
{
"results.product": "xyz",
"results.score": { "$gte": 6 }
},
{ "matched": 0 }
}},
{ "$group": {
"_id": "$_id",
"results": { "$push": "$results" },
"matched": { "$first": "$matched" }
}},
{ "$project": {
"results": {
"$cond": [
{ "$ne": [ "$matched", 0 ] },
"$results",
[]
]
}
}}
])
這是在設計和性能比較相當可怕的。因此,您最好在客戶端代碼中對每個文檔進行過濾。
因此,在所有情況下都要返回文檔,但要過濾數組內容?那麼所有的文檔都會返回,但只有符合條件的數組成員纔會返回。正確? –
是的,就像SQL中的左連接一樣 –