Reputation: 113
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.
Upvotes: 0
Views: 789
Reputation: 4261
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.
Upvotes: 1