Como observado, espero que seus documentos realmente tenham uma matriz, mas se $elemMatch estiver funcionando para você, eles deveriam.
De qualquer forma, você não pode classificar por um elemento em uma matriz usando find. Mas há um caso em que você pode fazer isso 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"
}}
])
Então, essencialmente, depois de fazer o
$match
condição para documentos que continham a correspondência relevante, você usa $projeto
"armazenar" o documento original no _id
campo e $unwind
uma "cópia" da matriz "entidades". O próximo
$match
"filtra" o conteúdo do array apenas para aqueles que são relevantes. Em seguida, você aplica o $sort
aos documentos "correspondentes". Como o documento "original" foi armazenado em
_id
, você usa $project
para "restaurar" a estrutura que o documento realmente tinha para começar. É assim que você "classifica" seu elemento correspondente de uma matriz.
Observe que se você tivesse várias "correspondências" em uma matriz para um documento pai, então você teria que empregar um
$grupo
stage para obter o valor $max para o campo "relevance" para concluir sua classificação.