I've just got stuck with this problem. I've got two Mongoose schemas:
var childrenSchema = mongoose.Schema({ name: { type: String }, age: { type: Number, min: 0 } }); var parentSchema = mongoose.Schema({ name : { type: String }, children: [childrenSchema] });
Question is, how to fetch all subdocuments (in this case, childrenSchema
objects) from every parent document? Let's suppose I have some data:
var parents = [ { name: "John Smith", children: [ { name: "Peter", age: 2 }, { name: "Margaret", age: 20 } ]}, { name: "Another Smith", children: [ { name: "Martha", age: 10 }, { name: "John", age: 22 } ]} ];
I would like to retrieve - in a single query - all children older than 18. Is it possible? Every answer will be appreciated, thanks!
The __v field is called the version key. It describes the internal revision of a document. This __v field is used to track the revisions of a document. By default, its value is zero ( __v:0 ). If you don't want to use this version key you can use the versionKey: false as mongoose.
So, basically, the id getter returns a string representation of the document's _id (which is added to all MongoDB documents by default and have a default type of ObjectId ). Regarding what's better for referencing, that depends entirely on the context (i.e., do you want an ObjectId or a string ).
The limit method will be used to return the maximum number of results from the collection, while the skip method is used to skip the number of documents from the collection in MongoDB. If we have one collection name as a student, student collection contains a hundred documents in it.
Mongoose Populate() Method In MongoDB, Population is the process of replacing the specified path in the document of one collection with the actual document from the other collection.
You can use $elemMatch
as a query-projection operator in the most recent MongoDB versions. From the mongo shell:
db.parents.find( {'children.age': {$gte: 18}}, {children:{$elemMatch:{age: {$gte: 18}}}})
This filters younger children's documents out of the children
array:
{ "_id" : ..., "children" : [ { "name" : "Margaret", "age" : 20 } ] } { "_id" : ..., "children" : [ { "name" : "John", "age" : 22 } ] }
As you can see, children are still grouped inside their parent documents. MongoDB queries return documents from collections. You can use the aggregation framework's $unwind
method to split them into separate documents:
> db.parents.aggregate({ $match: {'children.age': {$gte: 18}} }, { $unwind: '$children' }, { $match: {'children.age': {$gte: 18}} }, { $project: { name: '$children.name', age:'$children.age' } }) { "result" : [ { "_id" : ObjectId("51a7bf04dacca8ba98434eb5"), "name" : "Margaret", "age" : 20 }, { "_id" : ObjectId("51a7bf04dacca8ba98434eb6"), "name" : "John", "age" : 22 } ], "ok" : 1 }
I repeat the $match
clause for performance: the first time through it eliminates parents with no children at least 18 years old, so the $unwind
only considers useful documents. The second $match
removes $unwind
output that doesn't match, and the $project
hoists children's info from subdocuments to the top level.
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