Il framework di aggregazione
e non il .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"
}}
])
Probabilmente è meglio usare un "ancoraggio" all'inizio dell'espressione regolare se intendi dall '"inizio" della stringa. E anche facendo questo $match
prima di elaborare $unwind
anche:
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"
}}
])
Ciò assicura che tu non stia elaborando $unwind
su ogni documento della raccolta e solo su quelli che eventualmente contengono il tuo valore "tag abbinati" prima di "filtrare" per essere sicuro.
Il modo davvero "complesso" per mitigare in qualche modo grandi array con possibili corrispondenze richiede un po' più di lavoro e MongoDB 2.6 o versioni successive:
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" }}
])
Quindi $map
è un bel processore di array "in-line" ma può arrivare solo fino a questo punto. Il $setDifference
l'operatore nega il false
corrispondenze, ma alla fine devi ancora elaborare $unwind
per fare il restante $group
palcoscenico per valori distinti nel complesso.
Il vantaggio qui è che gli array ora sono "ridotti" solo all'elemento "tag" che corrisponde. Basta non usarlo quando vuoi un "conteggio" delle occorrenze quando ci sono valori "più distinti" nello stesso documento. Ma ancora una volta, ci sono altri modi per gestirlo.