Exemplo:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
mongodb
case-insensitive
Luke Dennis
fonte
fonte
$caseSensitive: false
. Veja: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
já é falso por padrão, e isso não responde à pergunta, porque funciona apenas em campos indexados. O OP estava procurando uma comparação de cadeias sem distinção entre maiúsculas e minúsculas.Respostas:
Você poderia usar um regex .
No seu exemplo, isso seria:
Devo dizer, no entanto, que talvez você deva apenas diminuir o valor (ou aumentar) o valor do caminho, em vez de incorrer no custo extra toda vez que o encontrar. Obviamente, isso não funcionará para nomes de pessoas e similares, mas talvez casos de uso como tags.
fonte
ATUALIZAR:
A resposta original agora está obsoleta. O Mongodb agora suporta pesquisa avançada de texto completo, com muitos recursos.
RESPOSTA ORIGINAL:
Deve-se notar que pesquisar com maiúsculas de minúsculas / i do regex significa que o mongodb não pode pesquisar por índice, portanto, consultas em conjuntos de dados grandes podem demorar muito tempo.
Mesmo com conjuntos de dados pequenos, não é muito eficiente. Você recebe um hit de CPU muito maior do que o exigido pela sua consulta, o que pode se tornar um problema se você estiver tentando obter escala.
Como alternativa, você pode armazenar uma cópia em maiúscula e pesquisar nela. Por exemplo, eu tenho uma tabela de usuário que possui um nome de usuário com letras maiúsculas e minúsculas, mas o id é uma cópia em maiúscula do nome de usuário. Isso garante que a duplicação com distinção entre maiúsculas e minúsculas é impossível (ter "Foo" e "foo" não serão permitidos), e eu posso pesquisar por id = nome_de_usuário.toUpperCase () para obter uma pesquisa que não diferencia maiúsculas de minúsculas de nome de usuário.
Se o seu campo for grande, como um corpo da mensagem, a duplicação de dados provavelmente não será uma boa opção. Acredito que usar um indexador estranho como o Apache Lucene é a melhor opção nesse caso.
fonte
username: 'bill'
correspondênciaBILL
ouBill
não uma consulta de pesquisa de texto completo, o que também jogo resultou palavras debill
, comoBills
,billed
etc.Se você precisar criar o regexp a partir de uma variável, é uma maneira muito melhor de fazê-lo: https://stackoverflow.com/a/10728069/309514
Você pode fazer algo como:
Isso tem o benefício de ser mais programático ou você pode obter um aumento de desempenho compilando-o com antecedência, se estiver reutilizando muito.
fonte
new RegExp("^" + req.params.term.toLowerCase(), "i")
também funciona bemLembre-se de que o exemplo anterior:
fará com que todas as entradas que contenham bar correspondam à consulta (bar1, barxyz, openbar), pode ser muito perigoso para uma pesquisa de nome de usuário em uma função de autenticação ...
Pode ser necessário que ele corresponda apenas ao termo de pesquisa, usando a sintaxe regexp apropriada como:
Consulte http://www.regular-expressions.info/ para obter ajuda de sintaxe sobre expressões regulares
fonte
A partir do MongoDB 3.4, a maneira recomendada de executar pesquisas rápidas que não diferenciam maiúsculas de minúsculas é usar um Índice Insensitivo a Maiúsculas .
Eu pessoalmente enviei um e-mail a um dos fundadores para que isso funcionasse, e ele fez isso acontecer! Foi um problema no JIRA desde 2009 e muitos solicitaram o recurso. Veja como funciona:
Um índice que não diferencia maiúsculas de minúsculas é feito especificando um agrupamento com uma força de 1 ou 2. Você pode criar um índice que não diferencia maiúsculas de minúsculas como este:
Você também pode especificar um agrupamento padrão por coleção ao criá-los:
Nos dois casos, para usar o índice que não diferencia maiúsculas de minúsculas, é necessário especificar o mesmo agrupamento na
find
operação que foi usada ao criar o índice ou a coleção:Isso retornará "Nova York", "Nova York", "Nova York" etc.
Outras notas
username: 'bill'
correspondênciaBILL
ouBill
não uma consulta de pesquisa de texto completo, que também corresponderia a palavras derivadas debill
, comoBills
,billed
etc.As respostas sugerindo o uso de expressões regulares são lentas, porque mesmo com índices, a documentação afirma :
$regex
As respostas também correm o risco de injeção de entrada do usuário .fonte
fonte
TL; DR
Maneira correta de fazer isso no mongo
Não use RegExp
Seja natural E use a indexação embutida do mongodb, pesquise
Passo 1 :
Passo 2 :
É necessário criar um índice no campo TEXT que você deseja pesquisar, sem que a consulta de indexação seja extremamente lenta
etapa 3 :
fonte
username: 'bill'
correspondênciaBILL
ouBill
não uma consulta de pesquisa de texto completo, o que também jogo resultou palavras debill
, comoBills
,billed
etc.fonte
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
O Mongo (versão atual 2.0.0) não permite pesquisas que diferenciam maiúsculas de minúsculas em campos indexados - consulte a documentação deles . Para campos não indexados, as expressões regulares listadas nas outras respostas devem estar corretas.
fonte
Uma coisa muito importante a ter em mente ao usar uma consulta baseada em Regex - Ao fazer isso para um sistema de login, escape a cada caractere que você está procurando e não esqueça os operadores ^ e $. O Lodash tem uma boa função para isso , se você já o estiver usando:
Por quê? Imagine um usuário digitando
.*
como seu nome de usuário. Isso corresponderia a todos os nomes de usuário, permitindo um login apenas adivinhando a senha de qualquer usuário.fonte
O melhor método está no seu idioma de escolha, ao criar um wrapper de modelo para seus objetos, faça com que o método save () itere através de um conjunto de campos nos quais você estará pesquisando que também são indexados; esses conjuntos de campos devem ter contrapartes em minúsculas que são usadas na pesquisa.
Sempre que o objeto é salvo novamente, as propriedades em minúsculas são verificadas e atualizadas com quaisquer alterações nas propriedades principais. Isso fará com que você possa pesquisar com eficiência, mas oculte o trabalho extra necessário para atualizar os campos lc a cada vez.
Os campos em minúsculas podem ser uma chave: armazenar objeto de valor ou apenas o nome do campo com um lc_ prefixado. Eu uso o segundo para simplificar a consulta (a consulta profunda a objetos pode ser confusa às vezes).
Nota: você deseja indexar os campos lc_, não os campos principais dos quais eles se baseiam.
fonte
Suponha que você queira pesquisar "coluna" em "Tabela" e deseje uma pesquisa sem distinção entre maiúsculas e minúsculas. A melhor e mais eficiente maneira é a seguinte;
O código acima apenas adiciona seu valor de pesquisa como RegEx e pesquisa com critérios insensíveis definidos com "i" como opção.
Muito bem sucedida.
fonte
Usando o Mongoose, isso funcionou para mim:
fonte
.toLowerCase()
redundante não é se você estiver especificando o sinalizador que não diferencia maiúsculas de minúsculasi
?A estrutura de agregação foi introduzida no mongodb 2.2. Você pode usar o operador de string "$ strcasecmp" para fazer uma comparação sem distinção entre maiúsculas e minúsculas. É mais recomendado e mais fácil do que usar regex.
Aqui está o documento oficial sobre o operador de comando de agregação: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
fonte
Você pode usar índices sem distinção entre maiúsculas e minúsculas :
O exemplo a seguir cria uma coleção sem agrupamento padrão e adiciona um índice no campo de nome com um agrupamento sem distinção entre maiúsculas e minúsculas. Componentes internacionais para Unicode
Para usar o índice, as consultas devem especificar o mesmo agrupamento.
ou você pode criar uma coleção com agrupamento padrão:
fonte
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Para pesquisar uma variável e escapar dela:
Escapar da variável protege a consulta contra ataques com '. *' Ou outro regex.
escape-string-regexp
fonte
Use RegExp . Caso outras opções não funcionem, o RegExp é uma boa opção. Isso torna a string insensível.
use o nome de usuário nas consultas e pronto.
Espero que funcione para você também. Muito bem sucedida.
fonte
Eu criei um Func simples para o regex que não diferencia maiúsculas de minúsculas, que eu uso no meu filtro.
Então você simplesmente filtra em um campo da seguinte maneira.
fonte
Usar um filtro funciona para mim em C #.
Pode até usar o índice porque acredito que os métodos são chamados após o retorno, mas ainda não testei isso.
Isso também evita um problema de
que o mongodb pensará que p.Title.ToLower () é uma propriedade e não será mapeado corretamente.
fonte
Para quem usa Golang e deseja ter uma pesquisa de texto completo com distinção entre maiúsculas e minúsculas com o mongodb e a biblioteca mgo godoc globalsign .
fonte
Como você pode ver nos documentos do mongo - como o
$text
índice da versão 3.2 não diferencia maiúsculas de minúsculas por padrão: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivityCrie um índice de texto e use o operador $ text na sua consulta .
fonte
username: 'bill'
correspondênciaBILL
ouBill
não uma consulta de pesquisa de texto completo, o que também jogo resultou palavras debill
, comoBills
,billed
etc.Estes foram testados para pesquisas de string
fonte
Eu já havia enfrentado um problema semelhante e foi isso que funcionou para mim:
fonte
$regex
e$options
. O que você Ctrl + F?$regex
é ineficiente e potencialmente inseguro, como expliquei na minha edição desta outra resposta de 2016 . Não há vergonha em excluir respostas se elas não servirem mais à comunidade!