简体   繁体   中英

How to get a list of unique elements of each type of a particular field- MongoDB

Suppose we have the following collection

[
    {
        'item' : 'A',
        'colors' : [
               'a1', 'a2', 'a3'
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    },
    {
        'item' : 'A',
        'colors' : [
               'c1', 'c2', 'c3'
        ]
    },
    {
        'item' : 'A',
        'colors' : [
               'd1', 'd2', 'd3'
        ]
    }
]

I want to get the distinct values of each type of field. For example, in the above collection, I want to get the output as follows:

[
    {
        'item' : 'A',
        'colors' : [
               'a1', 'a2', 'a3','c1', 'c2', 'c3','d1', 'd2', 'd3'
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    }
]

I tried the following query: db.collection.aggregate([{$group:{_id:'$item',colors:{$addToSet: '$colors'}}}]) . But, this appends each individual list instead of generating a single list of only value. Something like this.

[
    {
        'item' : 'A',
        'colors' : [
               ['a1', 'a2', 'a3'],['c1', 'c2', 'c3'],['d1', 'd2', 'd3']
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    }
]

What should I change in my query? Thanks a lot in advance for your help.

Use $unwind to transform the array fields. Example

db.collection.aggregate([
  {
    // Output a document for each color values.
    $unwind: "$colors"
  },
  {
    $group: {
      // Groups the documents by item value
      _id: "$item",
      uniqueColorValues: {
        // Set - Store unique values
        // Add the value to array if it is not present
        $addToSet: "$colors"
      }
    }
  }
])

To get the sorted result you have to apply the unwind & group again as follows. Example

db.collection.aggregate([
       {
        // Output a document for each color values.
        $unwind: "$colors"
      },
      {
        $group: {
          // Groups the documents by item value
          _id: "$item",
          uniqueColorValues: {
            // Set - Store unique values
            // Add the value to array if it is not present
            $addToSet: "$colors"
          }
        }
      },
      {
        // Transform again with color values
        $unwind: "$uniqueColorValues"
      },
      {
        // Sort the records with array value color
        $sort: {
          "uniqueColorValues": 1
        }
      },
      {
        // Regroup with _id value item
        "$group": {
          "_id": "$_id",
          // Push the values to array this will preserve the array elemets order
          "uniqueColorValues": {
            "$push": "$uniqueColorValues"
          }
        }
      },
      {
     // Apply the sort on item value.
        $sort: {
          "_id": 1
        }
      }
    ])

You can find the aggregation pipeline stage details here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM