Zakładając, że chcesz, aby były wszystkie dokumenty, które mają wartość „punkty” jako „klucz” w tablicy, a następnie sortuj według „wartości” dla tego „klucza”, to jest to trochę poza zakresem .find()
metoda.
Powodem jest to, że zrobiłeś coś takiego
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
Problem polega na tym, że chociaż dopasowane elementy do mają pasujący klucz „punkt”, nie ma sposobu, aby powiedzieć, który data.v
masz na myśli dla tego rodzaju. Również sort
w .find()
wyniki nie zrobią czegoś takiego:
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
Który byłby próbował aby użyć operatora pozycyjnego w sortowaniu, zasadniczo mówiącego, który element ma użyć wartości v
na. Ale to nie jest obsługiwane i prawdopodobnie nie będzie, a dla najbardziej prawdopodobnego wyjaśnienia ta wartość „indeksu” byłaby prawdopodobnie inna w każdym dokumencie.
Ale tego rodzaju selektywne sortowanie może odbywać się za pomocą .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"
}}
])
Oczywiście zakłada to data
tablica ma tylko jeden element, który ma kluczowe punkty. Gdyby było więcej niż jeden, musiałbyś $group
przed czymś takim:
// 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"
}}
Jest więc jedno użycie .aggregate()
w celu wykonania złożonego sortowanie dokumentów i zwracanie oryginalnego wyniku dokumentu w całości.
Przeczytaj więcej o operatorach agregacji
oraz ogólne ramy. To przydatne narzędzie do nauki, które zabierze Cię poza .find()
.