I have a list of documents that looks like this:
config: {
_id: ObjectId('63c6a4b858612f44f37d4771'),
type: "TypeA",
priority: 1
}
config: {
_id: ObjectId('627279d3ba7aef5d6418c867'),
type: "TypeB",
priority: 3
}
config: {
_id: ObjectId('628b4d3ff5b1c1736c0b654a'),
type: "TypeC",
priority: 4
}
The type is unique. Is it possible to merge these documents into one document with the type as key of each object field, like this:
TypeA: {
_id: ObjectId('63c6a4b858612f44f37d4771'),
priority: 1
},
TypeB: {
_id: ObjectId('627279d3ba7aef5d6418c867'),
priority: 3
},
TypeC: {
_id: ObjectId('628b4d3ff5b1c1736c0b654a'),
priority: 4
}
I have tried something like this:
{
$project: {
newDoc: [
{
k:'$config.type',
v: {
id:'$config._id',
priority: '$config.priority'
}
}
]
}
}, {
'$replaceRoot': {
'newRoot': {
'$arrayToObject': '$newDoc'
}
}
}
That gives me documents that looks like this:
TypeA: {
_id: ObjectId('63c6a4b858612f44f37d4771'),
priority: 1
}
TypeB: {
_id: ObjectId('627279d3ba7aef5d6418c867'),
priority: 3
}
TypeC: {
_id: ObjectId('628b4d3ff5b1c1736c0b654a'),
priority: 4
}
But I need to merge these into one Document...
CodePudding user response:
One option is to $group
and use $arrayToObject
:
db.collection.aggregate([
{$group: {
_id: null,
data: {
$push: {
k: "$config.type",
v: {_id: "$config._id", priority: "$config.priority"}
}
}
}},
{$replaceRoot: {newRoot: {$arrayToObject: "$data"}}}
])
See how it works on the playground example
CodePudding user response:
You can try this aggregate:
db.collection.aggregate([
{
$group: {
_id: null,
activeConfigs: {$push: '$$ROOT'},
}
}
])
Which should give you the result:
[
{
_id: null,
activeConfigs: [
TypeA: {
_id: ObjectId('63c6a4b858612f44f37d4771'),
priority: 1
},
TypeB: {
_id: ObjectId('627279d3ba7aef5d6418c867'),
priority: 2
},
TypeC: {
_id: ObjectId('628b4d3ff5b1c1736c0b654a'),
priority: 5
}
]
}
]