Reputation: 715
I'm new in mongoDb. I have set two collections. 1) book 2) comments
book :
_id
title
author
posted
price
And comments is :
_id
bookId
comment
status
I want to get get those book's comment which has status = 1
.
I have tried this.
return new promise((resolve, reject) => {
db.collection('book').aggregate([
{
$lookup:{
from:'comments',
localField: "_id",
foreignField: "bookId",
as: "comments"
}
}
]).toArray().then((result) => {
if(result.length > 0){
res.send({ status: 1, message: "Success.", data:result });
}else{
res.send({ status: 0, message: "No data found." });
}
}).catch((err) => {
res.send({ status: 0, message: "Something went wrong."});
});
});
And when I call my API , I got this out in postman.
{
"status": 1,
"message": "Success.",
"data": [
{
"_id": "5bacad201bff841afb40791f",
"title": "Game of thrones",
"author": "John snow",
"posted": "16/07/1995",
"price": 1000,
"comments": [
{
"_id": "5bacc31aa2d365256cab31ce",
"bookId": "5bacad201bff841afb40791f",
"comment": "Winter is comming"
},
{
"_id": "5bacc3f65c716925df953615",
"bookId": "5bacad201bff841afb40791f",
"comment": "It has a level of politics"
},
{
"_id": "5bacd60ea38cc526f1fee1d1",
"bookId": "5bacad201bff841afb40791f",
"comment": "It has a level of politics",
"status": 1
}
]
},
{
"_id": "5bacad601bff841afb407920",
"title": "Breaking bed",
"author": "Haison burg",
"posted": "20/08/2002",
"price": 550,
"comments": []
}
]
}
I need data which comments has status 1 value. I have tried to use $match
after $lookup
but it not works. I have also tried to use $eq
which is also not works for me. It may possible that I set it in a wrong way due to I have just start learning mongodb.
Upvotes: 5
Views: 7925
Reputation: 10918
From MongoDB v3.6.3 onwards, the fastest query performance would be achieved like this:
Make sure you have an index on the bookId
and the status
fields in the comments
collection:
db.comments.createIndex({ "bookId": 1, "status": 1 })
And then use the new pipeline
attribute of the $lookup
stage (documentation):
db.books.aggregate([{
"$lookup": {
"from": "comments",
"let": { "bId": "$_id" },
"pipeline": [{
"$match": {
$expr: { $eq: [ "$bookId", "$$bId" ] },
"status": 1
}
}],
"as": "comments"
}
}])
Upvotes: 4
Reputation: 46451
You can use $addFields
and $filter
aggregation here
db.collection("book").aggregate([
{ "$lookup": {
"from": "comments",
"localField": "_id",
"foreignField": "bookId",
"as": "comments"
}},
{ "$addFields": {
"comments": {
"$filter": {
"input": "$comments",
"cond": { "$eq": ["$$this.status", 1] }
}
}
}}
])
Upvotes: 3