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

requête mongodb :$size avec $gt renvoie toujours 0

Vous ne pouvez pas faire cela comme il est en fait référencé dans la documentation pour $size . Ainsi, cet opérateur évalue seul un résultat "littéral" et ne peut pas être utilisé en conjonction avec des "opérateurs de gamme" tels que vous le demandez.

Vos seules vraies options sont de demander une "taille" qui n'est "pas égale à 0" en annulant la condition avec le $not opérateur. Ce qui est parfaitement valable :

db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });

Ou sinon testez avec l'autre incarnation de $size dans le cadre d'agrégation, tant que votre version de MongoDB est 2.6 ou supérieure :

db.userStats.aggregate([
    { "$group": {
         "_id": null,
         "count": {
             "$sum": {
                 "$cond": [
                     { "$gt": [ { "$size": "$sessions", 0 } ] },
                     1,
                     0
                 ]
             }
         }
    }}
])

Peut-être aussi avec le $where forme d'évaluation JavaScript :

db.userStats.count(function() { return this.sessions.length > 0 });

Mais probablement plus lent que la dernière version.

Ou en fait, vous pouvez simplement le faire avec "dot notation" , et le $exists opérateur :

db.userStats.count({ "sesssions.0": { "$exists": true } });

Comme l'idée générale est que s'il y a un élément à l'index 0 alors le tableau a une certaine longueur.

Tout dépend de votre approche, mais n'importe lequel de ces formulaires donne le bon résultat.

Mais pour obtenir les "meilleures" performances de MongoDB, n'en utilisez aucun de ces méthodes. Au lieu de cela, conservez le tableau "longueur" comme propriété du document que vous inspectez. Cela, vous pouvez "indexer" et les requêtes émises peuvent réellement accéder à cet index, ce qu'aucune des solutions ci-dessus ne peut faire.

Maintenez-le comme ceci :

db.userStats.update(
     { "_id": docId, "sessions": { "$ne": newItem } },
     {
         "$push": { "sessions": newItem },
         "$inc": { "countSessions": 1 }
     }
)

Ou pour supprimer :

db.userStats.update(
     { "_id": docId, "sessions": newItem  },
     {
         "$pull": { "sessions": newItem },
         "$inc": { "countSessions": -1 }
     }
)

Ensuite, vous pouvez simplement interroger sur "countSesssions" qui peut également indexer pour de meilleures performances :

db.userStats.find({ "countSessions": { "$gt": 0 } })

Et c'est la "meilleure" façon de le faire.