查詢是很好的,因爲它的文件相匹配,但「投影」是的,你可以用.find()
做什麼範圍之內,你需要.aggregate()
,並注意不要從陣列中刪除「圖像」項目,只有不匹配的「標籤」。
理想情況下,你做這個有MongoDB的3.2使用內$project
:
db.site_users.aggregate([
{ "$match": { "images.tags": "broken" }},
{ "$project": {
"email": 1,
"password": 1,
"images": {
"$filter": {
"input": "$images",
"as": "image",
"cond": {
"$setIsSubSet": [["broken"], "$$image.tags"]
}
}
}
}}
])
或者可能使用$map
和$setDifference
這也與MongoDB的2.6兼容,只要在「圖像」的內容是「獨一無二」的每個條目。這是由於「設置」操作,其中「套」是「獨一無二」:
db.site_users.aggregate([
{ "$match": { "images.tags": "broken" }},
{ "$project": {
"email": 1,
"password": 1,
"images": {
"$setDifference": [
{ "$map": {
"input": "$images",
"as": "image",
"in": {
"$cond": {
"if": { "$setIsSubSet": [["broken"], "$$image.tags" ] },
"then": "$$image",
"else": false
}
}
}},
[false]
]
}
}}
])
它可以在早期版本的MongoDB做,但可能是最好的避免因處理$unwind
對成本數組:
db.site_users.aggregate([
{ "$match": { "images.tags": "broken" }},
{ "$unwind": "$images" },
{ "$match": { "images.tags": "broken" }},
{ "$group": {
"_id": "$_id",
"email": { "$first": "$email" },
"password": { "$first": "$password" },
"images": { "$push": "$images" }
}}
])
由於通常使用$unwind
爲了這個目的,你是不是「聚集」任何事情,那麼,如果你沒有一個現代版本在其他實際可用的方法相當大的代價,這是通常最好接受在客戶端代碼中而不是在服務器上「過濾」數組內容本身。
因此,對於這種情況,您應該只使用$unwind
,其中數組條目將通過刪除不匹配項目的順序「顯着」減少。否則,處理成本可能高於傳輸數據的網絡成本,並且任何好處都將被否定。
如果你沒有現代版本,那麼得到一個。這些功能與實用和性能完全不同。
你的元素匹配似乎是在項目部分,而不是過濾器部分(但我可能會誤解)。嘗試:'db.site_users.find({'images.tags':「broken」,{images:{$ elemMatch:{'tags':'broken'}}},{images:1})。pretty()' ? –