Ако приемем, че това, което искате, са всички документи, които имат стойността "точки" като "ключ" в масива и след това сортирайте по "стойността" за този "ключ", тогава това е малко извън обхвата на .find()
метод.
Причината е, ако сте направили нещо подобно
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
Проблемът е, че въпреки че съответстващите елементи правят имат съвпадащия ключ на "точка", няма начин да се каже кой data.v
имате предвид за сортирането. Освен това, sort
в .find()
резултатите няма да направят нещо подобно:
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
Което би било опитващо за използване на позиционен оператор в рамките на сортиране, като по същество казва кой елемент да използва стойността на v
На. Но това не се поддържа и е малко вероятно да бъде и за най-вероятното обяснение тази стойност на „индекс“ вероятно ще бъде различна във всеки документ.
Но този вид селективен сортирането може да се извърши с помощта на .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"
}}
])
Разбира се, това предполага data
масивът съдържа само един елемент, който има ключови точки. Ако имаше повече от един, ще трябва да $group
преди сортирането по този начин:
// 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"
}}
Така че има едно използване на .aggregate()
за да направя някокомплекса сортиране на документи и въпреки това връщане на оригиналния документ в пълен размер.
Прочетете още малко за операторите за агрегиране
и общата рамка. Това е полезен инструмент за учене, който ви отвежда отвъд .find()
.