'Find by _id on an array of objects in mongodb database
I'm trying to find the id of an object inside an array of objects. That _id has the same field name _id as others in the document. This is my model (brief)
var CardSchema = new mongoose.Schema({
beName: String,
beLink: String,
cards: [{
cardType: String,
cardBundle: String
}]
This is an sample of my database content
_id: ObjectId(5a52540638086448bf4235e8)
beName: Name1
beLink: Link1
cards: Array
0: Object
cardType: type1
cardBundle: 1
_id: ObjectId(5a526749d0ddab4bcdcc1556)
1: Object
cardType: type2
cardBundle: 1
_id: ObjectId(5a526749d0ddab4bcdcc1557)
...
_id: ObjectId(5a52540638086448bf4235e9)
beName: Namex
beLink: Linkx
cards: Array
0: Object
cardType: typex
cardBundle: x
_id: ObjectId(5a526749d0ddab4bcdcc1598)
1: Object
cardType: type2
cardBundle: 1
_id: ObjectId(5a526749d0ddab4bcdcc1599)
I'm trying to find the id of an specific card like this
Cards.find({ _id: req.params.id}, function (err, post) {
if (err) return next(err);
res.json(post);
});
But I get an empty result
I also tried
Cards.find({ _id: new ObjectId(req.params.id)}...
Solution 1:[1]
You probably need to use an aggregate
function to $unwind
the array of cards to find the matching card based on _id
.
so, in mongoose instead of find
use aggregate
pipeline
sample doc
> db.cards.findOne()
{
"_id" : ObjectId("5a52f4136fe82b42b7439a21"),
"beName" : "Name1",
"beLink" : "Link1",
"cards" : [
{
"cardType" : "type1",
"cardBundle" : 1,
"_id" : "5a52f3a66f112b42b7439a20"
},
{
"cardType" : "type2",
"cardBundle" : 1,
"_id" : "5a52f3a66f112b42b7439a21"
}
]
}
aggregate function
> db.cards.aggregate([{$unwind: "$cards"}, {$match:{"cards._id" : "5a52f3a66f112b42b7439a20"}}] )
result doc
> db.cards.aggregate([{$unwind: "$cards"}, {$match:{"cards._id" : "5a52f3a66f112b42b7439a20"}}] ).pretty()
{
"_id" : ObjectId("5a52f4136fe82b42b7439a21"),
"beName" : "Name1",
"beLink" : "Link1",
"cards" : {
"cardType" : "type1",
"cardBundle" : 1,
"_id" : "5a52f3a66f112b42b7439a20"
}
}
>
You can optimise it further if you know the parent _id
, in the aggregate pipeline $match
by parent _id
, then $unwind
, then $match
on array card _id
> db.cards.aggregate([{$match:{"_id":ObjectId("5a52f4136fe82b42b7439a21")}},{$unwind: "$cards"}, {$match:{"cards._id" : "5a52f3a66f112b42b7439a20"}}] )
Solution 2:[2]
Question is a bit vague, but by looking at other answers and having the card's _id in the url, I guess you have the card _id and you want to find the parent document. if so, then you don't need an aggregate. a find query does the job:
db.cards.find({"cards._id": _id})
Solution 3:[3]
Try doing it like:
const ObjectId = require("mongodb").ObjectID,
/* some other statements */
let cardId = new ObjectId(req.params.id)
Cards.find({ _id: cardId}, function (err, post) {
if (err) return next(err);
res.json(post);
});
For Reference: https://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Ajay |