I am building a side project that uses a mongodb database. I am using the MERN stack to build out a web application with my data. I am using Mongoose to get data from my database on a NodeJS/Express server to build my REST API. Here is an example of the data I have. I have deeply nested subdocuments that I need to retrieve. Each user has an array of 'contacts'. Each 'contact' has an array of 'tasks'. I would like to get an array of all tasks that are nested in each user. For example, if a user has 2 contacts, and each contact has 3 tasks, I would like an array with 6 tasks.
{
userName: 'jdoe',
uid: 12343,
contacts: [
{
name: 'Jane Doe',
tasks:[
{
taskName: 'Task1'
},
{
taskName: 'Task2'
},
{
taskName: 'Task3'
},
]
},
{
name: 'Bob Smith',
tasks:[
{
taskName: 'TaskA'
},
{
taskName: 'TaskB'
},
{
taskName: 'TaskC'
},
]
}
]
}
To query my data with Mongoose, I tried something like this
User.findOne({uid: req.params.uid}, 'contacts.tasks', (yasks,err)=>{
if(err){
res.send(err)
}else{
res.send(tasks)
}
})
However, this query returns something like this
{
"_id": "353453",
"contacts": [
{
"tasks": [
{
taskName: 'Task1'
}
]
},
{
"tasks": [
{
taskName: 'Task1'
},
{
taskName: 'Task1'
}
]
},
{
"tasks": []
},
{
"tasks": []
}
]
}
I am looking for a response such as this
[
{
taskName: 'Task1'
},
{
taskName: 'Task1'
},
taskName: 'Task1'
},
{
taskName: 'Task1'
}
]
I am wondering if there is any way I can do this with Mongoose. If not, what kind of javascript can I run to transform my data to be structured like this?
CodePudding user response:
You can use $reduce
for this:
User.aggregate([
{$match: {uid: req.params.uid}},
{
$project: {
tasks: {
$reduce: {
input: "$contacts",
initialValue: [],
in: {$concatArrays: ["$$value", "$$this.tasks"]}
}
},
_id: 0
}
}
])
See how it works on the playground example