Let's say I have a following collection with _id
and traits
.
{
_id: 1,
traits: {
Rarity: {
infoin: 15,
},
Type: {
iron: 3,
sliver: 5,
wood: 7,
},
},
},
{
_id: 2,
traits: {
Cloth: {
barron1: 11,
barron2: 12,
},
Hair: {
black: 6,
yellow: 9,
red: 8
}
},
},
...
As you can see keys of traits
are dynamic and keys of sub objects as well.
Here is the result I wanna get:
{
_id: 1,
traits: 15,
},
{
_id: 2,
traits: 23
}
Tip:
infocoin = iron sliver wood
barron1 barron2 = black yellow red
CodePudding user response:
$set
- SettraitObjs
array field by converting the object to array via$objectToArray
.$set
- SetfirstTraitValues
field by getting the value of first document fromtraitObjs
array, then converting from object to array via$objectToArray
.$project
- Decorate the output document. Settraits
field by convertingfirstTraitValues
array to number type with$reduce
and$sum
all thev
values.
db.collection.aggregate([
{
$set: {
traitObjs: {
$objectToArray: "$traits"
}
}
},
{
$set: {
firstTraitValues: {
$objectToArray: {
$first: "$traitObjs.v"
}
}
}
},
{
$project: {
traits: {
$reduce: {
input: "$firstTraitValues",
initialValue: 0,
in: {
$sum: [
"$$value",
"$$this.v"
]
}
}
}
}
}
])
Since all the values in the first key document and the second key document of traits
are the same,
infocoin = iron sliver wood
barron1 barron2 = black yellow red
Hence the above approach just sums up all the values in the first key document of traits
.