I have below document structure in mongodb:
{name: String, location: [String]}
Example documents are:
{name: "XYZ", location: ["A","B","C","D"]},
{name: "XYZ", location: ["M","N"]},
{name: "ABC", location: ["P","Q","R","S"]}
I want to write a query that when searches for a specific name, concats all location arrays of resulting documents. For example, If I search for name XYZ
, I should get:
{name:"XYZ",location:["A","B","C","D","M","N"]}
I guess this is possible using aggregation that might use $unwind
operator, but I am unable to frame the query.
Please help me to frame the query.
Thanks!
CodePudding user response:
$match
- Filter document(s).$group
- Group byname
. Add thelocation
array into thelocation
field via$push
. It results in thelocation
with the value of the nested array.$project
- Decorate the output document. With the$reduce
operator transforms the originallocation
array which is a nested array to be flattened by combining arrays into one via$concatArrays
.
db.collection.aggregate([
{
$match: {
name: "XYZ"
}
},
{
$group: {
_id: "$name",
location: {
$push: "$location"
}
}
},
{
$project: {
_id: 0,
name: "$_id",
location: {
$reduce: {
input: "$location",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
]
}
}
}
}
}
])
CodePudding user response:
This should do the trick:
Match the required docs. Unwind the location array. Group by name, and project the necessary output.
db.collection.aggregate([
{
"$match": {
name: "XYZ"
}
},
{
"$unwind": "$location"
},
{
"$group": {
"_id": "$name",
"location": {
"$push": "$location"
}
}
},
{
"$project": {
name: "$_id",
location: 1,
_id: 0
}
}
])