Here is my mongoose schema:
const chapterSchema = mongoose.Schema({
title: {
type: String
},
number: {
type: Number
}
})
const bookSchema = mongoose.Schema({
title: {
type: String
},
author: {
type: String
},
chapters: [chapterSchema]
})
const Book = mongoose.model('Book', bookSchema)
module.exports = Book
Here is my database:
{
"_id": "5f56f8e66a7eee227c1acc0a",
"title": "Book1",
"author": "Author1",
"chapters": [{
"_id": "5f56fa47a78fbf03cc32d16d",
"title": "Chapter1",
"number": 1
}, {
"_id": "5f56fad10820300de031317f",
"title": "Chapter2",
"number": 2,
}]
}
I want to find a specific chapter from the chapters array by it's id. So, I wrote this code:
router.get('/:id', async function (req, res) {
try {
const id = req.params.id
await Book.findById(id, function (err, chapter) {
res.render('chapter.hbs', {
chapter: chapter
})
})
} catch (error) {
res.redirect('/')
}
})
According to the chapter id, I want this result:
{
"_id": "5f56fa47a78fbf03cc32d16d",
"title": "Chapter1",
"number": 1
}
or
{
"_id": "5f56fad10820300de031317f",
"title": "Chapter2",
"number": 2,
}
What should I do to find a specific chapter using it's id?
You are searching on Book using findById of chapters Id, it will not give result since it is not Book Id,
You will need to use $elemMatch
for this
check this Querying for Object in Mongoose Sub Array for reference
You can do this using the aggregate function.
router.get('/:id', async function (req, res) {
try {
const id = req.params.id
await Books.aggregate([
{
$project: {
title: 1,
author: 1,
chapters: {
$filter: {
input: "$chapters",
as: "chapter",
cond: {
$eq: [
"$$chapter.id", id
]
}
}
}
}
}
])
} catch (error) {
res.redirect('/')
}
})
You can use aggregate()
function,
$match
your condition $filter
to get specific chapter id $replaceWith
to replace chapter in root const id = mongoose.Types.ObjectId(req.params.id);
let chapter = await Book.aggregate([
{ $match: { "chapters._id": id } },
{
$replaceWith: {
$arrayElemAt: [
{
$filter: {
input: "$chapters",
cond: { $eq: ["$$this._id", id] }
}
},
0
]
}
}
]);
console.log(chapter);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.