Supondo que o que você deseja sejam todos os documentos que tenham o valor "pontos" como uma "chave" na matriz e, em seguida, classifique o "valor" para essa "chave", isso está um pouco fora do escopo do
.find()
método. Razão é se você fez algo assim
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
O problema é que mesmo que os elementos correspondentes fazem tem a chave correspondente de "ponto", não há como dizer qual
data.v
você está se referindo para o tipo. Além disso, um sort
dentro de .find()
resultados não farão algo assim:db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
O que seria tentar para usar um operador posicional dentro de uma classificação, essencialmente informando qual elemento usar o valor de
v
sobre. Mas isso não é suportado e provavelmente não será, e para a explicação mais provável, esse valor de "índice" provavelmente seria diferente em cada documento. Mas esse tipo de seletivo a classificação pode ser feita com o uso de
.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"
}}
])
É claro que isso pressupõe os
data
array tem apenas o um elemento que tem os pontos-chave. Se houvesse mais de um, você precisaria $group
antes do tipo assim: // 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"
}}
Portanto, há um uso de
.aggregate()
para fazer alguns complexos classificação em documentos e ainda retornar o resultado do documento original na íntegra. Leia mais sobre operadores de agregação e o quadro geral. É uma ferramenta útil para aprender que leva você além de
.find()
.