I have this data stored in database.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{
"title": "Task Four testing 2",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes test",
"completed": false,
"_id": "62ff74bfe80b11ade2d34456"
},
{
"name": "do homework",
"completed": false,
"_id": "62ff74bfe80b11ade2d34457"
}
],
"_id": "62ff74bfe80b11ade2d34455"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v":0
}
I want to be able to return a single object with the id equal to the req.params.id, in this case that would be 62ff74bfe80b11ade2d34455.
{
"title": "Task Four testing 2",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes test",
"completed": false,
"_id": "62ff74bfe80b11ade2d34456"
},
{
"name": "do homework",
"completed": false,
"_id": "62ff74bfe80b11ade2d34457"
}
],
"_id": "62ff74bfe80b11ade2d34455"
}
I researched stackoverflow and came across this potential solution: Mongoose retrieve one document from nested array which implemented the aggregate framework. But when I test this in postman, the request isn't made.
const getTask = asyncHandler(async (req, res) => {
const task = await Board.aggregate([
{
$match: {
"columns.tasks._id": req.params.id,
},
},
{
$project: {
columns: {
$first: {
$filter: {
input: "$columns.tasks",
cond: {
$eq: ["$$this._id", req.params.id],
},
},
},
},
},
},
{
$replaceRoot: {
newRoot: "$columns",
},
},
]);
});
CodePudding user response:
Having an array inside an array complicates the query a bit, but here's one way to retrieve the data you want.
db.Board.aggregate([
{
$match: {
"columns.tasks._id": req.params.id
}
},
{"$unwind": "$columns"},
{
$match: {
"columns.tasks._id": req.params.id
}
},
{
"$project": {
"task": {
"$first": {
"$filter": {
"input": "$columns.tasks",
"cond": {"$eq": ["$$this._id", req.params.id]}
}
}
}
}
},
{"$replaceWith": "$task"}
])
Try it on mongoplayground.net. [The mongoplayground.net example uses "62ff74bfe80b11ade2d34455"
rather than req.params.id
.]