Die Abfrage ist gut, wie es das Dokument übereinstimmt, aber die „Projektion“ ist außerhalb des Rahmens, was Sie mit .find()
tun können, müssen Sie .aggregate()
und etwas Sorgfalt darauf verwendet, die "Bilder" -Elemente nicht aus dem Array zu entfernen und nur die nicht passenden "Tags".
Idealer Sie tun dies mit MongoDB 3.2 mit $filter
innen $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"]
}
}
}
}}
])
Oder vielleicht $map
und $setDifference
verwendet, die ebenfalls mit MongoDB 2.6, solange die „Bilder“ Inhalt „einzigartig“ ist kompatibel für jeder Eintrag. Dies ist aufgrund der „set“ Operation, bei der „Sets“ sind „einzigartig“:
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]
]
}
}}
])
Es kann in früheren Versionen von MongoDB getan werden, aber möglicherweise aufgrund der Kosten für die Verarbeitung am besten vermieden $unwind
auf die Array:
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" }
}}
])
Da es bei der Verwendung $unwind
zu diesem Zweck in der Regel eine erhebliche Kosten ist, wo Sie nicht alles „Aggregation“, dann, wenn Sie, wo die anderen praktische Ansätze zur Verfügung keine moderne Version haben, ist es oft am besten, um den Array-Inhalt selbst im Client-Code und nicht auf dem Server zu "filtern".
Sie sollten also nur auf $unwind
für diesen Fall zurückgreifen, wo die Array-Einträge "erheblich" reduziert werden würden, um die nicht übereinstimmenden Elemente zu entfernen. Andernfalls sind die Verarbeitungskosten wahrscheinlich höher als die Netzwerkkosten für die Übertragung der Daten, und jeder Vorteil wird negiert.
Wenn Sie keine moderne Version haben, dann holen Sie sich eine. Die Eigenschaften machen den Unterschied zu praktisch und performant.
Ihre elem Übereinstimmung scheint in der Projekt-Sektion statt der Filter-Sektion zu sein (Aber ich könnte mich irren). Versuchen Sie: 'db.site_users.find ({'images.tags':" kaputt ", {images: {$ elemMatch: {'tags': 'kaputt'}}}, {images: 1}). Pretty()' ? –