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

Comprimento do valor do campo de string no mongoDB


Para MongoDB 3.6 e mais recente:

O $expr O operador permite o uso de expressões de agregação dentro da linguagem de consulta, assim você pode aproveitar o uso de $strLenCP operador para verificar o comprimento da string da seguinte forma:
db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } 
})

Para MongoDB 3.4 e mais recente:

Você também pode usar a estrutura de agregação com o $redact operador de pipeline que permite processar a condição lógica com o $cond operador e usa as operações especiais $$KEEP para "manter" o documento onde a condição lógica é verdadeira ou $$PRUNE para "remover" o documento onde a condição era falsa.

Esta operação é semelhante a ter um $project pipeline que seleciona os campos na coleção e cria um novo campo que contém o resultado da consulta de condição lógica e, em seguida, um $match subsequente , exceto que $redact usa um único estágio de pipeline que é mais eficiente.

Quanto à condição lógica, existem Operadores de Agregação de String que você pode usar $strLenCP operador para verificar o comprimento da string. Se o comprimento for $gt um valor especificado, então esta é uma correspondência verdadeira e o documento é "mantido". Caso contrário, é "podado" e descartado.

Considere executar a seguinte operação agregada que demonstra o conceito acima:
db.usercollection.aggregate([
    { "$match": { "name": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$gt": [ { "$strLenCP": "$name" }, 40] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    { "$limit": 2 }
])

Se estiver usando $where , tente sua consulta sem os colchetes:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

Uma consulta melhor seria verificar a existência do campo e, em seguida, verificar o comprimento:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2); 

ou:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 
40"}).limit(2); 

MongoDB avalia não-$where operações de consulta antes de $where expressões e não $where instruções de consulta podem usar um índice. Um desempenho muito melhor é armazenar o comprimento da string como outro campo e então você pode indexar ou pesquisar nele; aplicando $where será muito mais lento comparado a isso. É recomendável usar expressões JavaScript e o $where como último recurso quando você não pode estruturar os dados de outra forma, ou quando está lidando com um pequeno subconjunto de dados.

Uma abordagem diferente e mais rápida que evita o uso do $where operador é o $regex operador. Considere o seguinte padrão que procura por
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2); 

Observação - Dos documentos :

Se existir um índice para o campo, o MongoDB fará a correspondência da expressão regular com os valores no índice, o que pode ser mais rápido do que uma varredura de coleção. Uma otimização adicional pode ocorrer se a expressão regular for uma “expressão de prefixo”, o que significa que todas as correspondências em potencial começam com a mesma string. Isso permite que o MongoDB construa um “intervalo” a partir desse prefixo e apenas corresponda aos valores do índice que se enquadram nesse intervalo.

Uma expressão regular é uma “expressão de prefixo” se começar com acaret (^) ou uma âncora esquerda (\A) , seguido por uma sequência de símbolos simples. Por exemplo, a regex /^abc.*/ será otimizado combinando apenas com os valores do índice que começam com abc .

Além disso, enquanto /^a/, /^a.*/, e /^a.*$/ corresponder a cadeias equivalentes, elas têm características de desempenho diferentes. Todas essas expressões usam um índice se existir um índice apropriado; no entanto,/^a.*/ e /^a.*$/ são mais lentos. /^a/ pode parar de verificar após corresponder ao prefixo.