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 comabc
.
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.