sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB encuentra subdocumento y ordena los resultados

Como se señaló, espero que sus documentos realmente tengan una matriz, pero si $elemMatch funciona para usted, entonces debería hacerlo.

En cualquier caso, no puede ordenar por un elemento en una matriz usando find. Pero hay un caso en el que puede hacer esto 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"
    }}
])

Básicamente, después de hacer $match condición para los documentos que contenían la coincidencia relevante, luego usa $project "almacenar" el documento original en el _id y $unwind una "copia" de la matriz de "entidades".

El siguiente $match "filtra" el contenido de la matriz a solo aquellos que son relevantes. Luego aplica el $sort a los documentos "emparejados".

Como el documento "original" se almacenó en _id , utiliza $project para "restaurar" la estructura con la que el documento realmente tenía al principio.

Así es como se "ordena" el elemento coincidente de una matriz.

Tenga en cuenta que si tenía varias "coincidencias" dentro de una matriz para un documento principal, entonces tendría que emplear un $group etapa para obtener el valor $max para el campo "relevancia" para completar su clasificación.