Exemple:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
mongodb
case-insensitive
Luke Dennis
la source
la source
$caseSensitive: false
. Voir: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
est déjà faux par défaut, et cela ne répond pas à la question, car cela ne fonctionne que sur les champs indexés. OP recherchait une comparaison de chaînes insensible à la casse.Réponses:
Vous pouvez utiliser une expression régulière .
Dans votre exemple, ce serait:
Je dois dire, cependant, que vous pourriez peut-être simplement réduire (ou augmenter) la valeur en cours de route plutôt que d'engager des frais supplémentaires chaque fois que vous la trouvez. Évidemment, cela ne fonctionnera pas pour les noms des gens et autres, mais peut-être des cas d'utilisation comme des balises.
la source
METTRE À JOUR:
La réponse originale est désormais obsolète. Mongodb prend désormais en charge la recherche avancée en texte intégral, avec de nombreuses fonctionnalités.
RÉPONSE ORIGINALE:
Il convient de noter que la recherche avec la majuscule insensible à la casse de regex / i signifie que mongodb ne peut pas rechercher par index, donc les requêtes sur de grands ensembles de données peuvent prendre beaucoup de temps.
Même avec de petits ensembles de données, ce n'est pas très efficace. Vous prenez un coup de processeur beaucoup plus grand que vos garanties de requête, ce qui pourrait devenir un problème si vous essayez d'atteindre l'échelle.
Comme alternative, vous pouvez stocker une copie en majuscules et rechercher par rapport à cela. Par exemple, j'ai une table User qui a un nom d'utilisateur qui est une casse mixte, mais l'ID est une copie en majuscule du nom d'utilisateur. Cela garantit que la duplication sensible à la casse est impossible (avoir à la fois "Foo" et "foo" ne sera pas autorisé), et je peux rechercher par id = username.toUpperCase () pour obtenir une recherche insensible à la casse pour le nom d'utilisateur.
Si votre champ est grand, comme un corps de message, la duplication de données n'est probablement pas une bonne option. Je crois que l'utilisation d'un indexeur étranger comme Apache Lucene est la meilleure option dans ce cas.
la source
username: 'bill'
correspondanceBILL
ouBill
, pas une requête de recherche en texte intégral, qui correspondrait également aux mots dérivés debill
, tels queBills
,billed
etc.Si vous devez créer l'expression rationnelle à partir d'une variable, c'est une bien meilleure façon de le faire: https://stackoverflow.com/a/10728069/309514
Vous pouvez alors faire quelque chose comme:
Cela a l'avantage d'être plus programmatique ou vous pouvez obtenir une amélioration des performances en le compilant à l'avance si vous le réutilisez beaucoup.
la source
new RegExp("^" + req.params.term.toLowerCase(), "i")
fonctionne aussi très bienGardez à l'esprit que l'exemple précédent:
fera en sorte que toutes les entrées contenant bar correspondent à la requête (bar1, barxyz, openbar), cela pourrait être très dangereux pour une recherche de nom d'utilisateur sur une fonction d'authentification ...
Vous devrez peut-être le faire correspondre uniquement au terme de recherche en utilisant la syntaxe d'expression rationnelle appropriée:
Voir http://www.regular-expressions.info/ pour obtenir de l'aide sur la syntaxe des expressions régulières
la source
À partir de MongoDB 3.4, la méthode recommandée pour effectuer des recherches rapides insensibles à la casse consiste à utiliser un index insensible à la casse .
J'ai personnellement envoyé un e-mail à l'un des fondateurs pour que cela fonctionne, et il l'a fait! C'était un problème sur JIRA depuis 2009 , et beaucoup ont demandé la fonctionnalité. Voici comment ça fonctionne:
Un index insensible à la casse est créé en spécifiant un classement avec une force de 1 ou 2. Vous pouvez créer un index insensible à la casse comme ceci:
Vous pouvez également spécifier un classement par défaut par collection lorsque vous les créez:
Dans les deux cas, pour utiliser l'index insensible à la casse, vous devez spécifier le même classement dans l'
find
opération qui a été utilisée lors de la création de l'index ou de la collection:Cela renverra "New York", "new york", "New york" etc.
Autres notes
Les réponses suggérant d'utiliser la recherche en texte intégral sont incorrectes dans ce cas (et potentiellement dangereuses ). La question était de faire une requête insensible à la casse, par exemple une
username: 'bill'
correspondanceBILL
ouBill
pas une requête de recherche en texte intégral, qui correspondrait également à des mots issus debill
, tels queBills
,billed
etc.Les réponses suggérant d'utiliser des expressions régulières sont lentes, car même avec des index, la documentation indique :
$regex
les réponses courent également le risque d’ injection d’entrée utilisateur .la source
la source
TL; DR
Manière correcte de le faire en mongo
N'utilisez pas RegExp
Devenez naturel et utilisez l'indexation intégrée de Mongodb, recherchez
Étape 1 :
Étape 2 :
Besoin de créer un index sur le champ TEXTE que vous souhaitez rechercher, sans requête d'indexation sera extrêmement lent
étape 3 :
la source
username: 'bill'
correspondanceBILL
ouBill
, pas une requête de recherche en texte intégral, qui correspondrait également aux mots dérivés debill
, tels queBills
,billed
etc.la source
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
Mongo (version actuelle 2.0.0) n'autorise pas les recherches non sensibles à la casse dans les champs indexés - voir leur documentation . Pour les champs non indexés, les expressions rationnelles répertoriées dans les autres réponses devraient être correctes.
la source
Une chose très importante à garder à l'esprit lors de l'utilisation d'une requête basée sur Regex - Lorsque vous faites cela pour un système de connexion, échappez à chaque caractère que vous recherchez et n'oubliez pas les opérateurs ^ et $. Lodash a une fonction intéressante pour cela , si vous l'utilisez déjà:
Pourquoi? Imaginez un utilisateur entrant
.*
comme son nom d'utilisateur. Cela correspondrait à tous les noms d'utilisateur, permettant une connexion en devinant simplement le mot de passe de n'importe quel utilisateur.la source
La meilleure méthode est dans la langue de votre choix, lorsque vous créez un wrapper de modèle pour vos objets, demandez à votre méthode save () de parcourir un ensemble de champs sur lesquels vous effectuerez une recherche qui sont également indexés; cet ensemble de champs doit avoir des équivalents en minuscules qui sont ensuite utilisés pour la recherche.
Chaque fois que l'objet est à nouveau enregistré, les propriétés en minuscules sont ensuite vérifiées et mises à jour avec toutes les modifications apportées aux propriétés principales. Cela vous permettra de rechercher efficacement, mais masquera le travail supplémentaire nécessaire pour mettre à jour les champs lc à chaque fois.
Les champs en minuscules peuvent être un magasin d'objets clé: valeur ou simplement le nom du champ avec un lc_ préfixé. J'utilise le second pour simplifier l'interrogation (l'interrogation d'objet profonde peut parfois prêter à confusion).
Remarque: vous souhaitez indexer les champs lc_, pas les champs principaux dont ils sont basés.
la source
Supposons que vous vouliez rechercher "colonne" dans "Table" et que vous vouliez une recherche sans distinction de casse. Le moyen le plus efficace et le plus efficace est le suivant;
Le code ci-dessus ajoute simplement votre valeur de recherche en tant que RegEx et recherche avec des critères insensibles définis avec l'option "i".
Bonne chance.
la source
En utilisant Mongoose, cela a fonctionné pour moi:
la source
.toLowerCase()
redondant si vous spécifiez l'indicateur insensible à la casse dei
?Le cadre d'agrégation a été introduit dans mongodb 2.2. Vous pouvez utiliser l'opérateur de chaîne "$ strcasecmp" pour effectuer une comparaison insensible à la casse entre les chaînes. C'est plus recommandé et plus facile que d'utiliser regex.
Voici le document officiel sur l'opérateur de commande d'agrégation: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
la source
Vous pouvez utiliser des index insensibles à la casse :
L'exemple suivant crée une collection sans classement par défaut, puis ajoute un index sur le champ de nom avec un classement insensible à la casse. Composants internationaux pour Unicode
Pour utiliser l'index, les requêtes doivent spécifier le même classement.
ou vous pouvez créer une collection avec un classement par défaut:
la source
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Pour rechercher une variable et l'échapper:
L'échappement de la variable protège la requête contre les attaques avec '. *' Ou une autre expression régulière.
escape-string-regexp
la source
Utilisez RegExp , si aucune autre option ne fonctionne pour vous, RegExp est une bonne option. Cela rend la chaîne insensible à la casse.
utilisez le nom d'utilisateur dans les requêtes, puis c'est fait.
J'espère que cela fonctionnera aussi pour vous. Bonne chance.
la source
J'ai créé un Func simple pour l'expression rationnelle insensible à la casse, que j'utilise dans mon filtre.
Ensuite, vous filtrez simplement sur un champ comme suit.
la source
L'utilisation d'un filtre fonctionne pour moi en C #.
Il peut même utiliser l'index car je pense que les méthodes sont appelées après le retour, mais je n'ai pas encore testé cela.
Cela évite également un problème de
que mongodb pensera que p.Title.ToLower () est une propriété et ne sera pas mappé correctement.
la source
Pour tous ceux qui utilisent Golang et souhaitent avoir une recherche plein texte sensible à la casse avec mongodb et la bibliothèque mgo godoc globalsign .
la source
Comme vous pouvez le voir dans les documents mongo - puisque l'
$text
index de la version 3.2 est insensible à la casse par défaut: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivityCréez un index de texte et utilisez l'opérateur $ text dans votre requête .
la source
username: 'bill'
correspondanceBILL
ouBill
, pas une requête de recherche en texte intégral, qui correspondrait également aux mots dérivés debill
, tels queBills
,billed
etc.Ceux-ci ont été testés pour les recherches de chaînes
la source
J'avais rencontré un problème similaire et c'est ce qui a fonctionné pour moi:
la source
$regex
et$options
. Qu'avez-vous fait Ctrl + F?$regex
est inefficace et potentiellement non sécurisée, comme je l'ai expliqué dans ma modification de cette autre réponse de 2016 . Il n'y a aucune honte à supprimer les réponses si elles ne servent plus la communauté!