MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongodb-Abfrage:$size mit $gt gibt immer 0 zurück

Sie können dies nicht tun, da tatsächlich in der Dokumentation für $size . Dieser Operator allein wertet also ein "literales" Ergebnis aus und kann es nicht in Verbindung mit "Bereichsoperatoren" verwendet werden, wie Sie fragen.

Ihre einzige wirkliche Möglichkeit besteht darin, nach einer "Größe" zu fragen, die "ungleich 0" ist, indem Sie die Bedingung mit $not Operator. Was vollkommen gültig ist:

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

Oder testen Sie andernfalls mit der anderen Inkarnation von $size im Aggregationsframework, solange Ihre MongoDB-Version 2.6 oder höher ist:

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

Eventuell auch mit dem $where Form der JavaScript-Auswertung:

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

Aber wahrscheinlich langsamer als die letzte Version.

Oder Sie können dies einfach mit "dot notation" , und der $exists Betreiber:

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

Als allgemeine Idee gilt, wenn es ein Element am Index 0 gibt dann hat das Array eine gewisse Länge.

Es hängt alles von Ihrem Ansatz ab, aber jedes dieser Formulare liefert das richtige Ergebnis.

Aber für die "beste" Leistung von MongoDB verwenden Sie keine dieser Methoden. Behalten Sie stattdessen das Array "Länge" als Eigenschaft des Dokuments bei, das Sie untersuchen. Dies können Sie "indizieren" und die ausgegebenen Abfragen können tatsächlich auf diesen Index zugreifen, was keines der oben genannten Verfahren kann.

Pflegen Sie es wie folgt:

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

Oder zu entfernen:

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

Dann können Sie einfach "countSessions" abfragen, die auch für die beste Leistung indizieren können:

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

Und das ist der "beste" Weg, es zu tun.