MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB trova il documento secondario e ordina i risultati

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.