kerangka kerja agregasi
dan bukan .distinct()
perintah:
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"
}}
])
Anda mungkin lebih baik menggunakan "jangkar" ke awal regex yang Anda maksud dari "awal" string. Dan juga melakukan ini $match
sebelum Anda memproses $unwind
juga:
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"
}}
])
Itu memastikan Anda tidak memproses $unwind
pada setiap dokumen dalam koleksi dan hanya dokumen yang mungkin berisi nilai "tag yang cocok" sebelum Anda "memfilter" untuk memastikan.
Cara yang benar-benar "kompleks" untuk sedikit mengurangi array besar dengan kemungkinan kecocokan membutuhkan sedikit lebih banyak pekerjaan, dan MongoDB 2.6 atau lebih besar:
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" }}
])
Jadi $map
adalah prosesor array "in-line" yang bagus tetapi hanya bisa sejauh ini. $setDifference
operator meniadakan false
cocok, tetapi pada akhirnya Anda masih perlu memproses $unwind
untuk melakukan $group
remaining yang tersisa panggung untuk nilai yang berbeda secara keseluruhan.
Keuntungannya di sini adalah bahwa array sekarang "direduksi" menjadi hanya elemen "tag" yang cocok. Hanya saja, jangan gunakan ini ketika Anda menginginkan "hitungan" kemunculan ketika ada "beberapa nilai berbeda" dalam dokumen yang sama. Tapi sekali lagi, ada cara lain untuk mengatasinya.