var thename = 'Andrew';
db.collection.find({'name':thename});
Как я могу запросить регистр без учета регистра? Я хочу найти результат, даже если "andrew";
var thename = 'Andrew';
db.collection.find({'name':thename});
Как я могу запросить регистр без учета регистра? Я хочу найти результат, даже если "andrew";
Решение Chris Fulstow будет работать (+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
.
Для этого вам нужно использовать не зависящее от регистра регулярное выражение, например
db.collection.find( { "name" : { $regex : /Andrew/i } } );
Чтобы использовать шаблон регулярного выражения из вашей переменной thename
, создайте новый объект RegExp:
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
Обновление: Для точного соответствия вам следует использовать регулярное выражение "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'}});
Я только что решил эту проблему несколько часов назад.
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
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
Следующий запрос найдет документы с требуемой строкой без учета и с глобальным вхождением также
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".
Вы можете использовать Нечувствительные к регистру индексы:
В следующем примере создается коллекция без сортировки по умолчанию, а затем добавляется индекс в поле имени с учетом нечувствительности к регистру. Международные компоненты для Юникода
/*
* 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