How can I flatten double arrays in mongoDB?
Your data for Countries are not in a good format, so you may consider to convert them. This is a script to flatten the array in Countries field and save it the origin documents that you can run in a mongo shell:
function flattenArray(inArr) {
var ret = [];
inArr.forEach(function(arr) {
if (arr.constructor.toString().indexOf("Array") > -1) {
ret = ret.concat(flattenArray(arr));
} else {
ret.push(arr);
}
});
return ret;
}
db.collection.find({
'Countries': {
'$exists': true
}
}).forEach(function(doc){
doc.Countries = flattenArray(doc.Countries);
db.collection.save(doc);
});
MongoDB flatten arbitrary nested arrays
I agree with @Joe's answer, No straight way to handle this kind of operation in MongoDB, You should think about your schema design as per your query requirement.
If you think you really needed this, you can try MongoDB Defines a custom aggregation function or expression in JavaScript, $function and $accumulator,
{
$project: {
data: {
$function: {
body: function(data) {
const flatten = arr => arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
return flatten(data);
},
args: ["$data"],
lang: "js"
}
}
}
}
Playground
IMPORTANT
Executing JavaScript inside an aggregation expression may decrease performance. Only use the
$function
operator if the provided pipeline operators cannot fulfill your application's needs.
Flatten MongoDB nested array in aggregation
You can use below aggregation. Use $map
to format the states array to include phase field.
db.docs.aggregate([
{"$addFields":{
"states":{
"$reduce":{
"input":"$phases",
"initialValue":[],
"in":{
"$concatArrays":[
"$$value",
{"$map":{
"input":"$$this.states",
"as":"state",
"in":{"phase":"$$this.type","type":"$$state.type","time":"$$state.time"}
}}
]
}
}
}
}}
])
Mongo Aggregation Flat nested arrays
Working on the assumption that FieldA
in your example is a placeholder that might be multiple fields or different names, you might
- $project to combine the top level
Billings
with the$extras
array - unwind
Extras
andBillings
so each document contains only one - Add the
ProjectId
andExtraId
to the billing object - Promote the
Billings
document to be the root
This will keep any fields in each Billings
document, and not require that you know the field names ahead of time.
db.collection.aggregate([
{"$project": {
_id: 0,
ProjectId: 1,
Extras: {
$concatArrays: [
[{ Billings: "$Billings" }],
"$Extras"
]
}
}},
{$unwind: "$Extras"},
{$unwind: "$Extras.Billings"},
{$addFields: {
"Extras.Billings.ExtraId": "$Extras.ExtraId",
"Extras.Billings.ProjectId": "$ProjectId"
}},
{$replaceRoot: {
newRoot: "$Extras.Billings"
}}
])
Playground
Return flattened array from each element in a nested array mongo with aggregation query
I would use $unwind
to flatten the array followed by $mergeObjects
to combine keys along with $replaceRoot
to promote the merge documents to the top.
Something like
db.colname.aggregate([
{$unwind:"$cars"},
{$replaceRoot:{newRoot:{$mergeObjects:[{owner:"$owner"}, "$cars"]}}}
])
Flatten nested arrays using mongodb aggregation in spring
This aggregation will help you achieve your result, except that you have to adapt it with Java
driver:
db.countries.aggregate([
{
"$unwind": "$cities"
},
{
"$project": {
"_id": 0,
"cities": 1
}
},
{
"$replaceRoot": {
"newRoot": "$cities"
}
}
])
How to flatted nested keys into the top level object in Mongoose
Maybe something like this using the aggregation framework:
db.collection.aggregate([
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$$ROOT",
"$attributes"
]
}
}
},
{
$project: {
attributes: 0
}
}
])
Explained:
- ReplaceRoot with merged object between the root object & attributes
- Remove the attributes object from the output.
playground
Related Topics
Svg Files in Raphael, Can They Be Used
Does It Matter If a Conditional Statement Comes Before or After the Expression
Rails Is Not Using My Global Ruby Version
Https Request Using Net::Http's Block Form -- Is It Possible
Ruby 'Range.Last' Does Not Give the Last Value. Why
Why #!/Usr/Bin/Env Ruby Doesn't Work in Crontab
Autoload Paths and Nested Services Classes Crash in Ruby
Upgrade Ruby on Elastic Beanstalk
What Could Be Causing This Rails Ioerror Closed Stream
Why Does the Break Statement in Ruby Behave Differently When Using Proc.New V. the Ampersand Sign
How to Make a Ruby Enumerator That Does Lazy Iteration Through Two Other Enumerators
Ruby Getting the Longest Word of a Sentence
Ruby Instance_Eval on a Class with Attr_Accessor
How to Catch Top Level Failures on an Eventmachine Server
Case-Insensitive Find_Or_Create_By_Whatever