MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

consulta mongodb:$size com $gt retorna sempre 0


Você não pode fazer isso como é realmente mencionado na documentação para $size . Portanto, esse operador sozinho avalia um resultado "literal" e não pode ser usado em conjunto com "operadores de alcance", como você está perguntando.

Suas únicas opções reais são pedir um "tamanho" que seja "diferente de 0" negando a condição com o $not operador. O que é perfeitamente válido:
db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });

Ou teste com a outra encarnação de $size na estrutura de agregação, desde que sua versão do MongoDB seja 2.6 ou superior:
db.userStats.aggregate([
    { "$group": {
         "_id": null,
         "count": {
             "$sum": {
                 "$cond": [
                     { "$gt": [ { "$size": "$sessions", 0 } ] },
                     1,
                     0
                 ]
             }
         }
    }}
])

Possivelmente também com o $where forma de avaliação JavaScript:
db.userStats.count(function() { return this.sessions.length > 0 });

Mas provavelmente mais lento que a última versão.

Ou, na verdade, você pode fazer isso com "notação de ponto" , e o $exists operador:
db.userStats.count({ "sesssions.0": { "$exists": true } });

Como a ideia geral é que se houver um elemento no índice 0 então a matriz tem algum comprimento.

Tudo depende da sua abordagem, mas qualquer uma dessas formas obtém o resultado certo.

Mas para o "melhor" desempenho do MongoDB, não use nenhum desses métodos. Em vez disso, mantenha a matriz "comprimento" como propriedade do documento que você está inspecionando. Isso você pode "indexar" e as consultas emitidas podem realmente acessar esse índice, o que nenhuma das opções acima pode fazer.

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

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

Então você pode apenas consultar "countSesssions", que também pode indexar para melhor desempenho:
db.userStats.find({ "countSessions": { "$gt": 0 } })

E essa é a "melhor" maneira de fazer isso.