Newbie Dev
Newbie Dev

Reputation: 69

Split arrays in set mongodb

I've been trying to make a set of strings < or arrays > but my main issue is that I can't use $unwind because of the other data. To make it more clear I'll show an example:

This is how part of my documents look like:

{
    "key": [
      "a",
      "b",
      "c"
    ]
  },
  {
    "key": [
      "b",
      "d"
    ]
  },
  {
    "key": [
      "e"
    ]
  }

And I want to get an array like this:

{
  "keys": [
     "a", 
     "b",
     "c",
     "d",
     "e"
  ]
}

or this:

{
  "keys": [
     ["a"], 
     ["b"],
     ["c"],
     ["d"],
     ["e"]
  ]
}

I just need unique values in there.

It would be so easy if I could use $unwind and then $addToSet. But as I said before I can't because of the other data that I need. I was trying to use $cond inside the $addToSet but I don't know how to iterate through an array.

This pipeline doesn't work ->

db.collection.aggregate([
  {
    "$group": {
      "_id": null,
      "keys": {
        "$addToSet": {
          "$concatArrays": [
            "$key",
            "$this"
          ]
        }
      },
      
    }
  }
])

Maybe something like this:

  {
    "$group": {
      "_id": null,
      "keys": {
        "$addToSet": {
          "$cond": {
            if: {
              "$gt": [
                {"$size": "$key"},
                1
              ]
            },
            then: "<SPLIT THE ARRAY IN THE AMOUNT OF ELEMENTS>",
            else: "$key"
          }
        }
      }
    }
  }

I tried this but it doesn't work either.

db.collection.aggregate([
  {
    "$project": {
      "keys": {
        "$map": {
          "input": {
            "$range": [
              0,
              {
                "$size": "$key"
              },
              1
            ]
          },
          as: "index",
          in: {
            $slice: [
              "$key",
              "$$index",
              1
            ]
          }
        }
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "keys": {
        "$addToSet": {
          "$concatArrays": [
            "$keys"
          ]
        }
      },
      
    }
  }
])

Here is my code snippet: https://mongoplayground.net/p/sMENXyrbQgI Could someone please guide me! I'll appreciate it so much.

Upvotes: 3

Views: 273

Answers (1)

Dheemanth Bhat
Dheemanth Bhat

Reputation: 4452

So the idea is to use $setUnion along with $reduce to pick unique values from the array:

Solution in MongoPlayground

Try this query:

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

Output:

{
    "_id" : null,
    "keys" : [
        "a",
        "b",
        "c",
        "d",
        "e"
    ]
}

Test data in collection:

[
    {
        "key": [
            "a",
            "b",
            "c"
        ]
    },
    {
        "key": [
            "b",
            "d",
            "a",
        ]
    },
    {
        "key": [
            "e",
            "b"
        ]
    }
]

Upvotes: 2

Related Questions