El marco de agregación
y no el .distinct()
comando:
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"
}}
])
Probablemente sea mejor usar un "anclaje" al comienzo de la expresión regular si quiere decir desde el "inicio" de la cadena. Y también haciendo esto $match
antes de procesar $unwind
también:
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"
}}
])
Eso asegura que no esté procesando $unwind
en todos los documentos de la colección y solo en aquellos que posiblemente contengan su valor de "etiquetas coincidentes" antes de "filtrar" para asegurarse.
La forma realmente "compleja" de mitigar un poco las matrices grandes con posibles coincidencias requiere un poco más de trabajo y MongoDB 2.6 o superior:
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" }}
])
Entonces $map
es un buen procesador de arreglos "en línea" pero solo puede llegar hasta cierto punto. El $setDifference
operador niega el false
coincide, pero en última instancia aún necesita procesar $unwind
para hacer el $group
restante escenario para distintos valores en general.
La ventaja aquí es que las matrices ahora se "reducen" solo al elemento "etiquetas" que coincide. Simplemente no use esto cuando desee un "recuento" de las ocurrencias cuando hay valores "múltiples distintos" en el mismo documento. Pero nuevamente, hay otras formas de manejar eso.