Ja, er zijn twee manieren om dit te doen. U kunt dus ofwel de $elemMatch
aan de projectiezijde zoals u al heeft, met kleine wijzigingen:
Model.findById(id,
{ "comments": { "$elemMatch": {"created.by": "Jane" } } },
function(err,doc) {
Of voeg gewoon toe aan het zoekgedeelte en gebruik de positionele $
operator:
Model.findOne(
{ "_id": id, "comments.created.by": "Jane" },
{ "comments.$": 1 },
function(err,doc) {
Hoe dan ook is volkomen geldig.
Als je iets meer betrokken wilt hebben dan dat, kun je de .aggregate()
methode en het is $project
operator in plaats daarvan:
Model.aggregate([
// Still match the document
{ "$match": "_id": id, "comments.created.by": "Jane" },
// Unwind the array
{ "$unwind": "$comments" },
// Only match elements, there can be more than 1
{ "$match": "_id": id, "comments.created.by": "Jane" },
// Project only what you want
{ "$project": {
"comments": {
"body": "$comments.body",
"by": "$comments.created.by"
}
}},
// Group back each document with the array if you want to
{ "$group": {
"_id": "$_id",
"comments": { "$push": "$comments" }
}}
],
function(err,result) {
Het aggregatieraamwerk kan dus voor veel meer worden gebruikt dan alleen het aggregeren van resultaten. Het is $project
operator geeft u meer flexibiliteit dan beschikbaar is voor projectie met behulp van .find()
. Je kunt er ook meerdere arrayresultaten mee filteren en retourneren, wat ook niet mogelijk is met projectie in .find()
.