Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the set of all unique values in array field

Given the following documents:

{ "_id" : ObjectId("585901b7875bab86885cf54f"), "foo" : 24, "bar" : [ 1, 2, 5, 6 ] }
{ "_id" : ObjectId("585901be875bab86885cf550"), "foo" : 42, "bar" : [ 3, 4 ] }

I want to get all the unique values in the bar field, something like:

{"_id": "something", "bar": [1, 2, 3, 4, 5, 6]}

This is what I tried:

db.stuff.aggregate([{
  $group: {
    _id: null, 
    bar: {
      $addToSet: {$each: "$bar"}
    }
  }
}])

But complains that $each is not a recognized operator.

This does work:

db.stuff.aggregate([{
  $group: {
    _id: null, 
    bar: {
      $addToSet: "$bar"
    }
  }
}])

But obviously produces a wrong result:

{ "_id" : null, "bar" : [ [ 3, 4 ], [ 1, 2, 5, 6 ] ] }

EDIT

I managed to have the result I want by adding a first $unwind stage:

db.stuff.aggregate([{
  $unwind: { "$bar" },
  $group: {
    _id: null, 
    bar: {
      $addToSet: "$bar"
    }
  }
}])

=> { "_id" : null, "bar" : [ 4, 3, 5, 2, 6, 1 ] }

Is it possible at all to make it in one single pipeline stage?

like image 806
skuro Avatar asked Oct 21 '25 12:10

skuro


1 Answers

The distinct() works with array field as well so will beautifully do this.

db.stuff.distinct('bar')

The aggregation framework is overkill for this and will not perform well

like image 142
styvane Avatar answered Oct 23 '25 07:10

styvane