Le framework d'agrégation
et non le .distinct()
commande :
db.event.aggregate([
// De-normalize the array content to separate documents
{ "$unwind": "$tags" },
// Filter the de-normalized content to remove non-matches
{ "$match": { "tags": /foo/ } },
// Group the "like" terms as the "key"
{ "$group": {
"_id": "$tags"
}}
])
Vous feriez probablement mieux d'utiliser une "ancre" au début de la regex, c'est-à-dire à partir du "début" de la chaîne. Et aussi en faisant cela $match
avant de traiter $unwind
aussi :
db.event.aggregate([
// Match the possible documents. Always the best approach
{ "$match": { "tags": /^foo/ } },
// De-normalize the array content to separate documents
{ "$unwind": "$tags" },
// Now "filter" the content to actual matches
{ "$match": { "tags": /^foo/ } },
// Group the "like" terms as the "key"
{ "$group": {
"_id": "$tags"
}}
])
Cela garantit que vous ne traitez pas $unwind
sur chaque document de la collection et uniquement ceux qui contiennent éventuellement votre valeur "balises correspondantes" avant de "filtrer" pour vous en assurer.
La manière vraiment "complexe" d'atténuer quelque peu les grands tableaux avec des correspondances possibles demande un peu plus de travail, et MongoDB 2.6 ou supérieur :
db.event.aggregate([
{ "$match": { "tags": /^foo/ } },
{ "$project": {
"tags": { "$setDifference": [
{ "$map": {
"input": "$tags",
"as": "el",
"in": { "$cond": [
{ "$eq": [
{ "$substr": [ "$$el", 0, 3 ] },
"foo"
]},
"$$el",
false
]}
}},
[false]
]}
}},
{ "$unwind": "$tags" },
{ "$group": { "_id": "$tags" }}
])
Donc $map
est un bon processeur "en ligne" de tableaux, mais il ne peut pas aller plus loin. Le $setDifference
l'opérateur nie le false
correspond, mais en fin de compte, vous devez toujours traiter $unwind
faire le reste du $group
étape pour des valeurs distinctes dans l'ensemble.
L'avantage ici est que les tableaux sont désormais "réduits" au seul élément "tags" qui correspond. Ne l'utilisez pas lorsque vous voulez un "compte" des occurrences lorsqu'il y a "plusieurs valeurs distinctes" dans le même document. Mais encore une fois, il existe d'autres façons de gérer cela.