I am struggling with retrieving nested document in root.
below i have a schema inside it there is a array of tasks in which objects are present, in those objects there is again an array of assigned objects and in those objects i have solution array.
now i want to merge all solutions in one array and get that solution array in root od document.
Schema -
{
_id: 1,
tasks: [
{
_id: 1,
assigned: [
{
_id: 1,
solutions: [
{
_id: 1,
name: 'solution 1',
},
{
_id: 2,
name: 'solution 2',
},
],
},
{
_id: 2,
solutions: [
{
_id: 1,
name: 'solution 1',
},
{
_id: 2,
name: 'solution 2',
},
],
},
],
},
],
};
I want to merge all solutions to a single array based on some condition and set that array into new field in root of collection.
const order = this.orderModel
.aggregate([
{ $match: { _id: orderId, student: studentId } },
{
$addFields: {
solutions: {
$map: {
input: '$tasks.assigned.solutions',
as: 's',
in: '$$s',
},
},
},
},
])
.exec();
output i am getting -
"solutions": [
[
[
{
"id": 1,
"name": "solution 1",
}
],
[
{
"_id": 2,
"name": "solution 2"
}
]
]
],
CodePudding user response:
Maybe something like this:
db.collection.aggregate([
{
"$project": {
"solutions": {
"$reduce": {
"input": "$tasks",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
{
$reduce: {
input: "$$this.assigned",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this.solutions"
]
}
}
}
]
}
}
}
}
}
])
Explained:
Use $project and two nested $reduce/$concatArrays to join the "solutions" array objects under the new array field "solutions" in the document root.
if you want to filter based on some condition you can replace "$$this.solutions" with:
{
$filter: {
input: "$$this.solutions",
cond: { $eq: ["$$this._id", 1] }
}
}
will filter only documents with _id:1
see example here