Za předpokladu, že to, co chcete, by byly všechny dokumenty, které mají hodnotu „body“ jako „klíč“ v poli, a poté seřadit podle „hodnoty“ pro tento „klíč“, pak je to trochu mimo rozsah .find()
metoda.
Důvodem je, pokud jste něco takového udělali
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
Problém je, že i když odpovídající prvky dělají mít odpovídající klíč „point“, neexistuje způsob, jak říct, který data.v
máte na mysli řazení. Také sort
v rámci .find()
výsledky neudělají něco takového:
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
Což by bylo snažení použít poziční operátor v rámci řazení, který v podstatě říká, který prvek má použít hodnotu v
na. Ale to není podporováno a pravděpodobně nebude, a pro nejpravděpodobnější vysvětlení, že hodnota "indexu" bude pravděpodobně v každém dokumentu jiná.
Ale tento druh selektivní třídění lze provést 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"
}}
])
To samozřejmě předpokládá data
pole má pouze jednu prvek, který má klíčové body. Pokud by jich bylo více, museli byste $group
před tímto řazením:
// 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"
}}
Existuje tedy jedno použití .aggregate()
s cílem udělat nějaký komplex třídění na dokumentech a přesto vrátit původní výsledek dokumentu v plném rozsahu.
Přečtěte si další informace o operátorech agregace
a obecný rámec. Je to užitečný nástroj k učení, který vás zavede za .find()
.