Как сделать запросы без учета регистра в Mongodb?



var thename = 'Andrew';
db.collection.find({'name':thename});


Как я могу запросить регистр нечувствителен? Я хочу найти результат, даже если "Андрей";

1153   10  

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

    Ничего не найдено.