MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Tri Mongo sur une condition calculée

Si vous voulez "pondérer" les résultats selon certains critères ou avoir n'importe quel type de "valeur calculée" dans un "tri", alors vous avez besoin du .aggregate() méthode à la place. Cela permet aux valeurs "projetées" d'être utilisées dans le $sort opération, pour laquelle seul un champ présent dans le document peut être utilisé :

db.messages.aggregate([
    { "$match": { "messages": userId } },
    { "$project": {
        "recipients": 1,
        "unread": 1,
        "content": 1,
        "readYet": {
            "$setIsSubset": [ [userId], "$unread" ] }
        }
    }},
    { "$sort": { "readYet": -1 } },
    { "$limit": 20 }
])

Ici le $setIsSubset L'opérateur permet la comparaison du tableau "non lu" avec un tableau converti de [userId] pour voir s'il y a des correspondances. Le résultat sera soit true où le userId existe ou false où ce n'est pas le cas.

Cela peut ensuite être passé à $sort , qui ordonne les résultats de préférence aux correspondances (le tri décroissant est true en haut ), et enfin $limit renvoie simplement les résultats jusqu'au montant spécifié.

Ainsi, afin d'utiliser un terme calulé pour "trier", la valeur doit être "projetée" dans le document afin qu'elle puisse être triée. Le cadre d'agrégation est la façon dont vous faites cela.

Notez également que $elemMatch n'est pas nécessaire uniquement pour correspondre à une seule valeur dans un tableau, et vous n'avez qu'à spécifier la valeur directement. Son but est de remplir les conditions "multiples" sur un seul élément de tableau, ce qui bien sûr ne s'applique pas ici.