Home > OS >  concat array fields of all matching documents mongodb
concat array fields of all matching documents mongodb

Time:10-11

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:

  1. $match - Filter document(s).

  2. $group - Group by name. Add the location array into the location field via $push. It results in the location with the value of the nested array.

  3. $project - Decorate the output document. With the $reduce operator transforms the original location 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"
            ]
          }
        }
      }
    }
  }
])

Demo @ Mongo Playground

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
    }
  }
])

Playground link.

  • Related