Se possibile, ti suggerirei di memorizzare sempre (doppio) il valore su cui desideri eseguire l'ordinamento. Mettilo nell'array e in un secondo campo. Ogni volta che inserisci un nuovo valore nell'array (o memorizzi l'array), aggiungi un nuovo campo corrispondente all '"ultimo valore nell'array" e quindi indicizza e ordina su quello. Nell'esempio seguente, l'ho chiamato lastR
:
{ "value" : -10, "r" : [ { "v" : 1 }, { "v" : 3 } ], "lastR": 3 }
{ "value" : 2, "r" : [ { "v" : 4 }, { "v" : 1 } ], "lastR": 1 }
{ "value" : -100, "r" : [ { "v" : 4 }, { "v" : 1 }, { "v" : 10 } ], "lastR": 10 }
{ "value" : -3, "r" : [ ] }
Crea un indice:
db.so.ensureIndex({lastR: 1})
E poi usa:
> db.so.find().sort({lastR: 1})
{ "_id" : ObjectId("5203a1c83c5438af60de63a1"), "value" : -3, "r" : [ ] }
{ "_id" : ObjectId("5203a1ad3c5438af60de639f"), "value" : 2, "r" : [ { "v" : 4 }, { "v" : 1 } ], "lastR" : 1 }
{ "_id" : ObjectId("5203a1d33c5438af60de63a2"), "value" : -10, "r" : [ { "v" : 1 }, { "v" : 3 } ], "lastR" : 3 }
{ "_id" : ObjectId("5203a1b73c5438af60de63a0"), "value" : -100, "r" : [ { "v" : 4 }, { "v" : 1 }, { "v" : 10 } ], "lastR" : 10 }
Sarà molto più versatile ed espandibile rispetto al tentativo di utilizzare una soluzione di aggregazione (che avrà un limite di 16 MB per il set di risultati e renderà molto più complesso recuperare documenti complessi quando è necessario gestire una proiezione).