Hello,
I have a document with nested arrays T and O like this one:
{
"_id": "XXX",
"T": [
{
"Classification": "GROUP A",
"O": [ "A", "B" ]
},
{
"Classification": "GROUP B",
"O": ["C", "D"]
}
]
}
I need to join all elements of O at T-level
{
"_id": "XXX",
"T": [
{
"Classification": "GROUP A",
"_O": "A,B"
},
{
"Classification": "GROUP B",
"_O": "C,D"
}
]
}
But I get “A,B,C,D” with my solution
db.O.aggregate( [{ $addFields: { ‘T._O’: { $function: { body: ‘function (x) { return x.join(','); }’, args: [ ‘$T.O’ ], lang: ‘js’ } } } }] )
A help will be highly appreciated.
I highly recommend not using $function
due to any JS on the server being slower than it needs to be.
The issue is that you are passing a single "$T.O"
to the JS function, and telling it to set a single "$T._O"
field so all the values of O
are being joined together. Here is how I would do it (without using JS):
db.O.aggregate([{$addFields:{T:{$map:{
input:"$T",
in: {$mergeObjects:[
"$$this",
{ _O: {$reduce: {
input:{$slice:["$$this.O", 1, {$size:"$$this.O"}]},
initialValue: {$arrayElemAt:["$$this.O",0]},
in: {$concat: ["$$value", ",", "$$this"]}
}}}
]}
}}}}])
That results in:
{
"_id" : "XXX",
"T" : [
{
"Classification" : "GROUP A",
"O" : [
"A",
"B"
],
"_O" : "A,B"
},
{
"Classification" : "GROUP B",
"O" : [
"C",
"D"
],
"_O" : "C,D"
}
]
}
Hi Asya,
thanks a lot.
I try to understand it:
To add a field to an array of objects i have to use $map together with $mergeObjects.
Then I get with $$this.O the nested array belongs to the actual object where I can join the elements with $reduce and $concat.
Greetings Axel
1 Like