Come notato, spero che i tuoi documenti abbiano effettivamente un array, ma se $elemMatch funziona per te, allora dovrebbero.
In ogni caso, non puoi ordinare in base a un elemento in un array usando find. Ma c'è un caso in cui puoi farlo usando .aggregate()
:
db.collection.aggregate([
// Match the documents that you want, containing the array
{ "$match": {
"nlp.entities": {
"$elemMatch": {
"text": "Neelie Kroes",
"type": "Person"
}
}
}},
// Project to "store" the whole document for later, duplicating the array
{ "$project": {
"_id": {
"_id": "$_id",
"url": "$url",
"nlp": "$nlp"
},
"entities": "$nlp.entities"
}},
// Unwind the array to de-normalize
{ "$unwind": "$entities" },
// Match "only" the relevant entities
{ "$match": {
"entities.text": "Neelie Kroes",
"entities.type": "Person"
}},
// Sort on the relevance
{ "$sort": { "entities.relevance": -1 } },
// Restore the original document form
{ "$project": {
"_id": "$_id._id",
"url": "$_id.url",
"nlp": "$_id.nlp"
}}
])
Quindi, in sostanza, dopo aver eseguito $match
condizione per i documenti che contenevano la corrispondenza pertinente, quindi utilizzare $project
"memorizza" il documento originale nel _id
campo e $unwind
una "copia" dell'array "entities".
Il prossimo $match
"filtra" il contenuto dell'array solo su quelli rilevanti. Quindi applichi $sort
ai documenti "abbinati".
Poiché il documento "originale" è stato archiviato in _id
, utilizzi $project
per "ripristinare" la struttura con cui il documento doveva effettivamente iniziare.
È così che "ordina" l'elemento abbinato di un array.
Tieni presente che se avevi più "corrispondenze" all'interno di un array per un documento padre, quindi dovresti utilizzare un ulteriore $group
fase per ottenere il valore $max per il campo "rilevanza" al fine di completare l'ordinamento.