Dengan asumsi bahwa yang Anda inginkan adalah semua dokumen yang memiliki nilai "poin" sebagai "kunci" dalam array, dan kemudian mengurutkan "nilai" untuk "kunci" itu, maka ini sedikit di luar cakupan untuk .find()
metode.
Alasannya adalah jika Anda melakukan sesuatu seperti ini
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
Masalahnya adalah meskipun elemen yang cocok lakukan memiliki kunci "titik" yang cocok, tidak ada cara untuk mengetahui yang mana data.v
Anda mengacu untuk semacam itu. Juga, sort
dalam .find()
hasil tidak akan melakukan hal seperti ini:
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
Yang akan mencoba untuk menggunakan operator posisi dalam pengurutan, pada dasarnya memberi tahu elemen mana yang menggunakan nilai v
pada. Tapi ini tidak didukung dan tidak mungkin, dan untuk penjelasan yang paling mungkin, bahwa nilai "indeks" kemungkinan akan berbeda di setiap dokumen.
Tapi jenis selektif penyortiran dapat dilakukan dengan menggunakan .aggregate()
.
db.collection.aggregate([
// Actually shouldn't need the setid
{ "$match": { "data": {"$elemMatch": { "k": "points" } } } },
// Saving the original document before you filter
{ "$project": {
"doc": {
"_id": "$_id",
"setid": "$setid",
"date": "$date",
"version": "$version",
"data": "$data"
},
"data": "$data"
}}
// Unwind the array
{ "$unwind": "$data" },
// Match the "points" entries, so filtering to only these
{ "$match": { "data.k": "points" } },
// Sort on the value, presuming you want the highest
{ "$sort": { "data.v": -1 } },
// Restore the document
{ "$project": {
"setid": "$doc.setid",
"date": "$doc.date",
"version": "$doc.version",
"data": "$doc.data"
}}
])
Tentu saja itu mengasumsikan data
array hanya memiliki satu elemen yang memiliki poin-poin penting. Jika ada lebih dari satu, Anda perlu $group
sebelum urutkan seperti ini:
// Group to remove the duplicates and get highest
{ "$group": {
"_id": "$doc",
"value": { "$max": "$data.v" }
}},
// Sort on the value
{ "$sort": { "value": -1 } },
// Restore the document
{ "$project": {
"_id": "$_id._id",
"setid": "$_id.setid",
"date": "$_id.date",
"version": "$_id.version",
"data": "$_id.data"
}}
Jadi ada satu penggunaan .aggregate()
untuk melakukan beberapa kompleks menyortir dokumen dan tetap mengembalikan hasil dokumen asli secara utuh.
Baca lebih lanjut tentang operator agregasi
dan kerangka umum. Ini adalah alat yang berguna untuk belajar yang membawa Anda melampaui .find()
.