Het aggregatieraamwerk
en niet de .distinct()
commando:
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"
}}
])
Het is waarschijnlijk beter om een "anker" aan het begin van de regex te gebruiken, je bedoelt vanaf het "begin" van de string. En doe dit ook $match
voordat u $unwind
verwerkt
ook:
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"
}}
])
Dat zorgt ervoor dat u $unwind
niet verwerkt
op elk document in de verzameling en alleen diegene die mogelijk uw "overeenkomende tags"-waarde bevatten voordat u "filtert" om er zeker van te zijn.
De echt "complexe" manier om grote arrays enigszins te verzachten met mogelijke overeenkomsten kost wat meer werk, en MongoDB 2.6 of hoger:
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" }}
])
Dus $map
is een mooie "in-line" processor van arrays, maar het kan maar zo ver gaan. De $setDifference
operator negeert de false
overeenkomsten, maar uiteindelijk moet je nog steeds $unwind
. verwerken om de resterende $group
. te doen podium voor verschillende waarden in het algemeen.
Het voordeel hiervan is dat arrays nu worden "gereduceerd" tot alleen het "tags" -element dat overeenkomt. Gebruik dit alleen niet als u een "telling" wilt van de voorkomens wanneer er "meerdere verschillende" waarden in hetzelfde document zijn. Maar nogmaals, er zijn andere manieren om daarmee om te gaan.