Collection:
[{
_id: "Jon"
gender: "male",
sockets: [
{ code: 12345, type: 'default' },
{ code: 67891, type: 'special' }
]
},
{
_id: "Jane"
gender: "female",
sockets: [
{ code: 445566, type: 'very_special' },
{ code: 223388, type: 'extra_special' }
]
}]
I want to run a search for the code field. So the user starts typing a code and should be suggested with found codes. E.g. when typing 1 results should be
[{
_id: "Jon", code: 12345
}, {
_id: "Jon", code: 67891
}]
I know I have to use aggregation with grouping. But I cannot find any example how to do this for my use case. If I would group by a standard field I would use this. But this does not apply to a sub-collection like sockets:
collection.aggregate([{
$group: {
_id: "$code"
}
}]);
Any ideas?
When you deal with "arrays" in the aggregation framework you generally want to $unwind first. This effectively "de-normalizes" your document into separate documents for each array entry.
The other thing here for the type of "grouping" you possibly want is that _id can contain a combination of fields to "group" on rather than just a single field value. Possibly no difference from just processing $unwind here in this example, but for an application of $group you do it like this:
db.collection.aggregate([
{ "$unwind": "$sockets" },
{ "$group": {
"_id": { "_id": "$_id", "code": "$sockets.code" }
}}
])
Generally you actually really want to "group" on something, but perhaps you just want the "de-normalized" form, which you can also do with $project:
db.collection.aggregate([
{ "$unwind": "$sockets" },
{ "$project": {
"_id": 1,
"code": "$sockets.code"
}}
])