Hello, im trying to query some nested documents at MongoDB. im using Mongoose.. my documents are like
[
{
"_id": "5a2ca2227c42ad67682731d4",
"description": "some descrition",
"photos": [
{
"_id": "5a2ca22b7c42ad67682731d5",
"approved": false,
"text":"good"
},
{
"_id": "5a2ca72b0a1aa173aaae07da",
"approved": true,
"text":"bad"
},
{
"_id": "5a2cabf85a41077a2f87d4e3",
"approved": false,
"text":"bad"
}
]
}
]
I Want to find only photos that have the value "good", at text attribute, here is my find code:
ObjectSchema.find({
'photos': {
$elemMatch : {
'text' : 'good'
}
}
},function(err,result){
console.log(result);
});
I Wanted only to return the objct with the element with value that match my query, but when one object of this list match, the whole list of photos come with the result, not only who match the text.. How can i query it, and bring only the element who match, in this case, only the element which have "good" in text..
im using nodejs + mongoose
Thank you!
Posted On: Jun 24, 2021. In Mongoose the “_v” field is the versionKey is a property set on each document when first created by Mongoose. This is a document inserted through the mongo shell in a collection and this key-value contains the internal revision of the document.
The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _id s we store here must be document _id s from the Story model. Note: ObjectId , Number , String , and Buffer are valid for use as refs.
You are using find
with only conditions, which will return entire documents. You can also specify a projection with find
to include/exclude certain fields from documents. You can use the $elemMatch in the projection as follows:
ObjectSchema.find({
'photos': {
$elemMatch : {
'text' : 'good'
}
}
}, {
'photos': {
$elemMatch : {
'text' : 'good'
}
}
}, function(err,result){
console.log(result);
});
But beware that $elemMatch in the projection will only include the first matching array element. That is probably not what you want based on the sample doc. Instead, you can use the Aggregation Framework. You can start with something like the following (untested) and shape the output as you prefer:
ObjectSchema.aggregate(
{$unwind: "$photos"},
{$match: {"photos.text": "good"}},
function(err,result){
console.log(result);
}
)
where the $unwind
makes a separate document for each element of the array.
To shape the output as you describe in the comment, you need to use a $group aggregation. Try adding the a $group aggregation similar to the following onto the end of pipeline:
{$group: {_id: "$_id", photos: {$push: "$photos"}}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With