var thename = 'Andrew';
db.collection.find({'name':thename});
Как сделать запрос без учета регистра? Я хочу найти результат, даже если "андрей";
var thename = 'Andrew';
db.collection.find({'name':thename});
Как сделать запрос без учета регистра? Я хочу найти результат, даже если "андрей";
Ответы:
Решение Криса Фулстоу будет работать (+1), однако оно может быть неэффективным, особенно если ваша коллекция очень большая. Некорневые регулярные выражения (те, которые не начинаются с ^
, которые привязывают регулярное выражение к началу строки) и те, которые используют i
флаг нечувствительности к регистру, не будут использовать индексы, даже если они существуют.
Альтернативный вариант, который вы можете рассмотреть, - денормализовать данные для хранения версии name
поля в нижнем регистре , например, как name_lower
. Затем вы можете эффективно запросить это (особенно если оно проиндексировано) для точных совпадений без учета регистра, например:
db.collection.find({"name_lower": thename.toLowerCase()})
Или с совпадением префикса (корневое регулярное выражение) как:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
Оба этих запроса будут использовать индекс name_lower
.
new RegExp('^'+ username + '$', "i")
чтобы оно было точным.
".*"
.
Для этого вам нужно будет использовать регулярное выражение без учета регистра , например
db.collection.find( { "name" : { $regex : /Andrew/i } } );
Чтобы использовать шаблон регулярного выражения из вашей thename
переменной, создайте новый объект RegExp :
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
Обновление: для точного совпадения вы должны использовать регулярное выражение "name": /^Andrew$/i
. Благодаря Яннику Л.
name
, а не только равенству.
{ "name": /^Andrew$/i }
Я решил это так.
var thename = 'Andrew';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
Если вы хотите запросить «точное соответствие без учета регистра», вы можете сделать это следующим образом.
var thename = '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
MongoDB 3.4 теперь включает в себя возможность создавать индекс без учета регистра, что резко увеличит скорость поиска без учета регистра в больших наборах данных. Он создается путем указания сопоставления с силой 2.
Вероятно, самый простой способ сделать это - установить параметры сортировки в базе данных. Затем все запросы наследуют это сопоставление и будут использовать его:
db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
Вы также можете сделать это так:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
И используйте это так:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
Это вернет города с названиями «Нью-Йорк», «Нью-Йорк», «Нью-Йорк» и т. Д.
Для получения дополнительной информации: https://jira.mongodb.org/browse/SERVER-90
С Mongoose (и Node) это сработало:
User.find({ email: /^name@company.com$/i })
User.find({ email: new RegExp(
`^ $ {emailVariable} $`, 'i')})
В MongoDB это сработало:
db.users.find({ email: { $regex: /^name@company.com$/i }})
Обе строки нечувствительны к регистру. Электронная почта в БД может быть, NaMe@CompanY.Com
и обе строки все равно найдут объект в БД.
Точно так же мы могли бы использовать, /^NaMe@CompanY.Com$/i
и он все равно находил бы электронную почту: name@company.com
в БД.
Чтобы найти нечувствительную к регистру строку, используйте это,
var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
Я решил эту проблему несколько часов назад.
var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
Вы даже можете расширить это, выбрав нужные поля в пользовательском объекте Andrew, сделав это следующим образом:
db.collection.find({ $text: { $search: thename } }).select('age height weight');
Ссылка: https://docs.mongodb.org/manual/reference/operator/query/text/#text
... с мангустом на NodeJS этот запрос:
const countryName = req.params.country;
{ 'country': new RegExp(`^${countryName}$`, 'i') };
или
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
// ^australia$
или
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
// ^turkey$
Полный пример кода на Javascript, NodeJS с Mongoose ORM на 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);
});
});
Следующий запрос найдет документы с требуемой строкой нечувствительно и также с глобальным появлением
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
Чтобы найти строку литералов без учета регистра:
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
Регулярные выражения работают медленнее, чем сопоставление буквальных строк. Однако дополнительное поле в нижнем регистре усложнит ваш код. В случае сомнений используйте регулярные выражения. Я бы посоветовал использовать поле с явно строчными буквами только в том случае, если оно может заменить ваше поле, то есть вас в первую очередь не волнует регистр.
Обратите внимание, что вам нужно будет экранировать имя до регулярного выражения. Если вам нужны подстановочные знаки, вводимые пользователем .replace(/%/g, '.*')
, лучше добавлять их после экранирования, чтобы вы могли сопоставить «a%», чтобы найти все имена, начинающиеся с «a».
Вы можете использовать индексы без учета регистра :
В следующем примере создается коллекция без параметров сортировки по умолчанию, а затем добавляется индекс в поле имени с параметрами сортировки без учета регистра. Международные компоненты для 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 } } )
Чтобы использовать индекс, запросы должны указывать одинаковые параметры сортировки.
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 } )
или вы можете создать коллекцию с сопоставлением по умолчанию:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
Простым способом было бы использовать $ toLower, как показано ниже.
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])