10 ответов:
Крис Fulstow будет работать (+1), однако, она не может быть эффективной, особенно если ваша коллекция очень большая. Некорневые регулярные выражения (те, которые не начинаются с
^, который привязывает регулярное выражение к началу строки), и те, кто используетiфлаг для регистра не будет использовать индексы, даже если они существуют.альтернативным вариантом, который вы можете рассмотреть, является денормализация ваших данных для хранения строчной версии
nameполе, например, какname_lower. Затем вы можете эффективно запросить это (особенно если оно индексировано) для точных совпадений без учета регистра, таких как:db.collection.find({"name_lower": thename.toLowerCase()})или с префиксом match (корневое регулярное выражение) как:
db.collection.find( {"name_lower": { $regex: new RegExp("^" + thename.toLowerCase(), "i") } } );оба этих запроса будут использовать индекс на
name_lower.
вам нужно будет использовать регистр без учетарегулярные выражения для этого, например,
db.collection.find( { "name" : { $regex : /Andrew/i } } );чтобы использовать шаблон регулярных выражений из вашего
thenameпеременная, построить новый и
Я решил это так.
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 } });
- чувствительность к регистру и диакритическая чувствительность устанавливаются в false по умолчанию при выполнении запросов таким образом.
вы даже можете расширить это, выбрав нужные вам поля из объекта пользователя 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... });
чтобы найти строку литералов без учета регистра:
С помощью regex (рекомендуется)
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
чтобы найти строку без учета регистра используйте это,
var thename = "Andrew"; db.collection.find({"name":/^thename$/i})
простой способ-использовать $toLower, как показано ниже.
db.users.aggregate([ { $project: { name: { $toLower: "$name" } } }, { $match: { name: the_name_to_search } } ])
Comments