John Lohith
John Lohith

Reputation: 102

Combining unique elements of arrays without $unwind

I would like to get the unique elements of all arrays in a collection. Consider the following collection

[
  {
    "collection": "collection",
    "myArray": [
      {
        "name": "ABC",
        "code": "AB"
      },
      {
        "name": "DEF",
        "code": "DE"
      }
    ]
  },
  {
    "collection": "collection",
    "myArray": [
      {
        "name": "GHI",
        "code": "GH"
      },
      {
        "name": "DEF",
        "code": "DE"
      }
    ]
  }
]

I can achieve this by using $unwind and $group like this:

db.collection.aggregate([
  {
    $unwind: "$myArray"
  },
  {
    $group: {
      _id: null,
      data: {
        $addToSet: "$myArray"
      }
    }
  }
])

And get the output:

[
  {
    "_id": null,
    "data": [
      {
        "code": "GH",
        "name": "GHI"
      },
      {
        "code": "DE",
        "name": "DEF"
      },
      {
        "code": "AB",
        "name": "ABC"
      }
    ]
  }
]

However, the array "myArray" will have a lot of elements (about 6) and the number of documents passed into this stage of the pipeline will be about 600. So unwinding the array would give me a total of 3600 documents being processed. I would like to know if there's a way for me to achieve the same result without unwinding

Upvotes: 1

Views: 179

Answers (1)

Ashh
Ashh

Reputation: 46451

You can use below aggregation

db.collection.aggregate([
  { "$group": {
    "_id": null,
    "data": { "$push": "$myArray" }
  }},
  { "$project": {
    "data": {
      "$reduce": {
        "input": "$data",
        "initialValue": [],
        "in": { "$setUnion": ["$$this", "$$value"] }
      }
    }
  }}
])

Output

[
  {
    "_id": null,
    "data": [
      {
        "code": "AB",
        "name": "ABC"
      },
      {
        "code": "DE",
        "name": "DEF"
      },
      {
        "code": "GH",
        "name": "GHI"
      }
    ]
  }
]

Upvotes: 1

Related Questions