MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB encontra subdocumento e classifica os resultados


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.