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

query mongodb:$size con $gt restituisce sempre 0

Non puoi farlo come viene effettivamente fatto riferimento nella documentazione per $size . Quindi quell'operatore da solo valuta un risultato "letterale" e non può essere utilizzato insieme agli "operatori di gamma" come stai chiedendo.

Le tue uniche opzioni reali sono chiedere una "dimensione" che sia "non uguale a 0" negando la condizione con $not operatore. Che è perfettamente valido:

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

Oppure prova con l'altra incarnazione di $size nel framework di aggregazione, purché la versione di MongoDB sia 2.6 o successiva:

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

Possibilmente anche con $where forma di valutazione JavaScript:

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

Ma probabilmente più lento dell'ultima versione.

Oppure puoi farlo semplicemente con "dot notation" e $exists operatore:

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

Poiché l'idea generale è che se c'è un elemento all'indice 0 quindi l'array ha una certa lunghezza.

Tutto dipende dal tuo approccio, ma ognuna di queste forme ottiene il risultato giusto.

Ma per ottenere le "migliori" prestazioni da MongoDB, non utilizzarne nessuno di questi metodi. Mantieni invece la "lunghezza" dell'array come proprietà del documento che stai ispezionando. Questo puoi "indicizzare" e le query emesse possono effettivamente accedere a quell'indice, cosa che nessuna delle precedenti può fare.

Mantienilo in questo modo:

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

O per rimuovere:

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

Quindi puoi semplicemente eseguire una query su "countSessions" che può anche indicizzare per le migliori prestazioni:

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

E questo è il modo "migliore" per farlo.