{
FullName: "Emily Clark",
Details: {
Income: [
{
2021: [
{
time: "Sun Apr 11 2021 17:42:39 GMT 0530 (India Standard Time)",
description: "Web",
amount: "3700",
},
{
time: "Sun May 21 2022 07:12:59 GMT 0530 (India Standard Time)",
description: "Pc Monitor",
amount: "45000",
},
],
},
{
2022: [
{
time: "Sat May 28 2022 12:23:34 GMT 0530 (India Standard Time)",
description: "Class",
amount: "4100",
},
],
},
],
Expense: [
{
2022: [
{
time: "Tue May 17 2022 20:30:39 GMT 0530 (India Standard Time)",
descritption: "Car Wash",
amount: 4000,
},
{
time: "Fri May 19 2022 10:23:29 GMT 0530 (India Standard Time)",
description: "Loundry",
amount: "300",
},
],
},
],
},
};
Here I firstly added a new Expense Data object to the Details.Income.0.2021
so it created a new array and object after Income, but after adding new Expense data for a new Year as 2022 it was added to the existing object of first income element, how to create a new array object for new year only if the year not exists?
The second Income element was added by me manually from MongoDB shell.
If the year exist I want the data to look like for Expense
where it has two Object data for both the same year.
I know this explanation is a little messy but I am willing to provide more information if needed.
CodePudding user response:
EDIT:
Since Income
and Expense
are arrays of objects, and each year is a key inside it, the all solution is rather complicated.
One option is to do something like:
- add the new item to the doc,
- calculate the
lastYear
on theIncome
- Add a new year if
lastYear
is not the same as the input yearyearString
- remove the last year from
Details.Income
in order to edit it. Keep it aslast
. - Add the new item to it.
- Merge it back to the original structure.
db.collection.update({
FullName: "Emily Clark"
},
[
{$addFields: {
newItem: {a: "test"},
year: yearString
}
},
{
$addFields: {
lastYear: {
$reduce: {
input: {$objectToArray: {$last: "$Details.Income"}},
initialValue: "",
in: {$concat: ["$$value", "$$this.k"]}
}
}
}
},
{
$addFields: {
newArr: {
$cond: [
{$eq: ["$lastYear", "$year"]},
[],
[{yearString: []}]
]
}
}
},
{
$set: {
"Details.Income": {
$concatArrays: ["$Details.Income", "$newArr"]
},
year: "$$REMOVE",
newArr: "$$REMOVE"
}
},
{
$set: {
last: {$objectToArray: {$last: "$Details.Income"}},
"Details.Income": {
$slice: ["$Details.Income", {$subtract: [{$size: "$Details.Income"}, 1]
}
]
}
}
},
{
$set: {
last: {
$map: {
input: "$last",
as: "item",
in: {
v: {$concatArrays: ["$$item.v", ["$newItem"]]},
k: "$$item.k"
}
}
}
}
},
{$set: {last: {$arrayToObject: ["$last"]}}},
{
$set: {
"Details.Income": {$concatArrays: ["$Details.Income", ["$last"]]},
last: "$$REMOVE",
newItem: "$$REMOVE",
lastYear: "$$REMOVE"
}
}
])
If Income
and Expense
were an object instead of array of objects it would be as simple as:
db.collection.update({
FullName: "Emily Clark"
},
{
$push: {
"Details.Expense.2022":
{
time: "Fri May 19 2022 10:23:29 GMT 0530 (India Standard Time)",
description: "Loundry",
amount: "300",
}
}
})