Search code examples
mongodbmongoosemongodb-queryaggregate

mongodb - How can I group documents with duplicates and sort their numbers to an array without duplicates?


Here is my sample data:

[
  { name: "bob",number:20 },
  { name: "bob",number:10 }, 
  { name: "kol",number:20 },
  { name: "bob",number:20 }
  { name: "kol",number:10 },
  { name: "kol",number:10 }
]

I want to get a document per name with an array of unique numbers sorted. expected output:

    [
      {
        name:"bob",
        number: [10,20] // with sort, not 20,10
      },
      {
        name:"kol",
        number: [10,20]
      }
    ]

I tried something like this but not working as I want. I did not get the array of numbers sorted.

user.aggregate([
        {
            $group: {
                _id: '$name',
                name: { $first: '$name' },
                number: {$addToSet: '$number'}
            }
        },
        {$sort: {name: 1}}
])

Solution

  • You just need to $sort before you $group by the name and use $push in order to keep all numbers, instead of $addToSet. For keeping the numbers a set just use $setIntersection to remove duplicates:

    db.collection.aggregate([
      {$sort: {number: 1}},
      {
        $group: {
          _id: "$name",
          number: {$push: "$number"}
        }
      },
      {
        $project: {
          name: "$_id",
          number: {$setIntersection: ["$number"]},
          _id: 0
        }
      },
    {$sort: {name: 1}}
    ])
    

    See how it works on the playground example