var thename = 'Andrew';
db.collection.find({'name':thename});
Comment faire une requête insensible à la casse? Je veux trouver le résultat même si "andrew";
var thename = 'Andrew';
db.collection.find({'name':thename});
Comment faire une requête insensible à la casse? Je veux trouver le résultat même si "andrew";
Réponses:
La solution de Chris Fulstow fonctionnera (+1), cependant, elle peut ne pas être efficace, surtout si votre collection est très grande. Les expressions régulières non enracinées (celles qui ne commencent pas par ^
, qui ancrent l'expression régulière au début de la chaîne) et celles qui utilisent l' i
indicateur d'insensibilité à la casse n'utiliseront pas d'index, même s'ils existent.
Une autre option que vous pourriez envisager est de dénormaliser vos données pour stocker une version minuscule du name
champ, par exemple sous la forme name_lower
. Vous pouvez ensuite interroger cela efficacement (surtout s'il est indexé) pour les correspondances exactes insensibles à la casse comme:
db.collection.find({"name_lower": thename.toLowerCase()})
Ou avec une correspondance de préfixe (une expression régulière enracinée) comme:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
Ces deux requêtes utiliseront un index sur name_lower
.
new RegExp('^'+ username + '$', "i")
pour être une correspondance exacte.
".*"
.
Vous auriez besoin d'utiliser une expression régulière insensible à la casse pour celui-ci, par exemple
db.collection.find( { "name" : { $regex : /Andrew/i } } );
Pour utiliser le modèle d'expression régulière de votre thename
variable, construisez un nouvel objet RegExp :
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
Mise à jour: pour une correspondance exacte, vous devez utiliser l'expression régulière "name": /^Andrew$/i
. Merci à Yannick L.
name
, pas seulement égal.
{ "name": /^Andrew$/i }
Je l'ai résolu comme ça.
var thename = 'Andrew';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
Si vous souhaitez interroger sur la «correspondance exacte insensible à la casse», vous pouvez procéder comme suit.
var thename = '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
MongoDB 3.4 inclut désormais la possibilité de créer un véritable index insensible à la casse, ce qui augmentera considérablement la vitesse des recherches insensibles à la casse sur de grands ensembles de données. Il est fait en spécifiant un classement avec une force de 2.
Le moyen le plus simple de le faire est probablement de définir un classement dans la base de données. Ensuite, toutes les requêtes héritent de ce classement et l'utiliseront:
db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
Vous pouvez également le faire comme ceci:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
Et utilisez-le comme ceci:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
Cela renverra les villes nommées «New York», «New York», «New York», etc.
Pour plus d'informations: https://jira.mongodb.org/browse/SERVER-90
Avec Mongoose (et Node), cela a fonctionné:
User.find({ email: /^name@company.com$/i })
User.find({ email: new RegExp(
`^ $ {emailVariable} $`, 'i')})
Dans MongoDB, cela a fonctionné:
db.users.find({ email: { $regex: /^name@company.com$/i }})
Les deux lignes sont insensibles à la casse. L'e-mail dans la base de données pourrait être NaMe@CompanY.Com
et les deux lignes trouveront toujours l'objet dans la base de données.
De même, nous pourrions utiliser /^NaMe@CompanY.Com$/i
et il trouverait toujours des e-mails: name@company.com
dans la base de données.
Pour trouver une chaîne insensible à la casse, utilisez ceci,
var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
Je viens de résoudre ce problème il y a quelques heures.
var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
Vous pouvez même développer cela en sélectionnant les champs dont vous avez besoin à partir de l'objet utilisateur d'Andrew en procédant de cette manière:
db.collection.find({ $text: { $search: thename } }).select('age height weight');
Référence: https://docs.mongodb.org/manual/reference/operator/query/text/#text
... avec mangouste sur NodeJS qui interroge:
const countryName = req.params.country;
{ 'country': new RegExp(`^${countryName}$`, 'i') };
ou
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
// ^australia$
ou
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
// ^turkey$
Un exemple de code complet en Javascript, NodeJS avec Mongoose ORM sur MongoDB
// get all customers that given country name
app.get('/customers/country/:countryName', (req, res) => {
//res.send(`Got a GET request at /customer/country/${req.params.countryName}`);
const countryName = req.params.countryName;
// using Regular Expression (case intensitive and equal): ^australia$
// const query = { 'country': new RegExp(`^${countryName}$`, 'i') };
// const query = { 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
const query = { 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
Customer.find(query).sort({ name: 'asc' })
.then(customers => {
res.json(customers);
})
.catch(error => {
// error..
res.send(error.message);
});
});
La requête suivante trouvera les documents avec la chaîne requise de manière insensible et avec une occurrence globale également
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
Pour rechercher une chaîne littérale insensible à la casse:
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
Les expressions régulières sont plus lentes que la correspondance de chaîne littérale. Cependant, un champ minuscule supplémentaire augmentera la complexité de votre code. En cas de doute, utilisez des expressions régulières. Je suggérerais de n'utiliser un champ explicitement minuscule que s'il peut remplacer votre champ, c'est-à-dire que vous ne vous souciez pas du cas en premier lieu.
Notez que vous devrez échapper le nom avant regex. Si vous voulez des caractères génériques saisis par l'utilisateur, préférez les ajouter .replace(/%/g, '.*')
après l'échappement afin de pouvoir faire correspondre "a%" pour trouver tous les noms commençant par "a".
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
/*
* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )
Pour utiliser l'index, les requêtes doivent spécifier le même classement.
db.users.insert( [ { name: "Oğuz" },
{ name: "oğuz" },
{ name: "OĞUZ" } ] )
// does not use index, finds one result
db.users.find( { name: "oğuz" } )
// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )
// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )
ou vous pouvez créer une collection avec le classement par défaut:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
Un moyen simple serait d'utiliser $ toLower comme ci-dessous.
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])