Das Aggregations-Framework
und nicht die .distinct()
Befehl:
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"
}}
])
Es ist wahrscheinlich besser, einen "Anker" am Anfang der Regex zu verwenden, wenn Sie vom "Anfang" der Zeichenfolge meinen. Und auch dabei $match
bevor Sie $unwind
verarbeiten
auch:
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"
}}
])
Dadurch wird sichergestellt, dass Sie nicht $unwind
verarbeiten
auf jedes Dokument in der Sammlung und nur auf diejenigen, die möglicherweise Ihren Wert "übereinstimmende Tags" enthalten, bevor Sie "filtern", um sicherzugehen.
Der wirklich "komplexe" Weg, große Arrays mit möglichen Übereinstimmungen etwas abzumildern, erfordert etwas mehr Arbeit und MongoDB 2.6 oder höher:
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" }}
])
Also $map
ist ein netter "Inline"-Prozessor von Arrays, aber er kann nur so weit gehen. Der $setDifference
-Operator negiert false
Übereinstimmungen, aber letztendlich müssen Sie immer noch $unwind
verarbeiten um die restlichen $group
zu erledigen Bühne für eindeutige Werte insgesamt.
Der Vorteil dabei ist, dass Arrays jetzt nur noch auf das passende "Tags"-Element "reduziert" werden. Verwenden Sie dies nur nicht, wenn Sie eine "Zählung" der Vorkommen wünschen, wenn es "mehrere unterschiedliche" Werte im selben Dokument gibt. Aber auch hier gibt es andere Möglichkeiten, damit umzugehen.