Tidak dapat mereproduksi kesalahan Anda tetapi Anda memiliki beberapa "salah ketik" dalam pertanyaan Anda, jadi saya tidak yakin apa yang sebenarnya Anda miliki.
Tetapi dengan anggapan Anda benar-benar bekerja dengan MongoDB 2.6 atau lebih tinggi maka Anda mungkin menginginkan $setIntersection
atau $setIsSubset
operator daripada $setUnion
. Operator tersebut menyiratkan konten "cocok" dari array yang dibandingkan dengan mereka, di mana $setUnion
cukup gabungkan array yang disediakan dengan yang sudah ada:
db.people.aggregate([
{ "$project": {
"first_name": 1,
"last_name": 1,
"sticky": {
"$size": {
"$setIntersection": [ "$offices", [ "FL", "SC" ]]
}
},
"offices": 1
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
Pada versi sebelumnya di mana Anda tidak memiliki set operator
tersebut anda hanya menggunakan $unwind
untuk bekerja dengan array, dan jenis $cond
operasi seperti sebelumnya dalam $group
untuk menyatukan semuanya kembali:
db.people.aggregate([
{ "$unwind": "$offices" },
{ "$group": {
"_id": "$_id",
"first_name": { "$first": "$first_name" },
"last_name": { "$first": "$last_name",
"sticky": { "$sum": { "$cond": [
{ "$or": [
{ "$eq": [ "$offices": "FL" ] },
{ "$eq": [ "$offices": "SC" ] },
]},
1,
0
]}},
"offices": { "$push": "$offices" }
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
Tapi Anda pasti berada di jalur yang benar. Cukup pilih operasi set yang tepat atau metode lain untuk mendapatkan kebutuhan Anda yang tepat.
Atau karena Anda telah memposting cara Anda mendapatkan apa yang Anda inginkan, cara yang lebih baik untuk menulis "pencocokan berurutan" semacam itu adalah ini:
db.people.aggregate([
{ "$project": {
"first_name": 1,
"last_name": 1,
"sticky": { "$cond": [
{ "$anyElementTrue": {
"$map": {
"input": "$offices",
"as": "o",
"in": { "$eq": [ "$$o", "FL" ] }
}
}},
2,
{ "$cond": [
{ "$anyElementTrue": {
"$map": {
"input": "$offices",
"as": "o",
"in": { "$eq": [ "$$o", "SC" ] }
}
}},
1,
0
]}
]},
"offices": 1
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
Dan itu akan memprioritaskan dokumen dengan "kantor" yang berisi "FL" di atas "SC" dan karenanya di atas semua yang lain, dan melakukan operasi dalam satu bidang. Itu juga akan sangat mudah bagi orang untuk melihat cara mengabstraksikannya ke dalam formulir menggunakan $unwind
di versi sebelumnya tanpa operator yang disetel. Di mana Anda cukup memberikan nilai "bobot" yang lebih tinggi ke item yang Anda inginkan di atas dengan menyarangkan $cond
pernyataan.