MongoDB: Можно ли сделать запрос без учета регистра? - PullRequest
265 голосов
/ 08 декабря 2009

Пример:

> db.stuff.save({"foo":"bar"});

> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0

Ответы [ 23 ]

5 голосов
/ 06 мая 2016

Одна очень важная вещь, о которой следует помнить при использовании запроса на основе регулярных выражений - когда вы делаете это для системы входа в систему, экранирует каждый отдельный символ , который вы ищете, и не забывайте ^ и $ операторы. В Lodash есть хорошая функция для этого , если вы уже используете ее:

db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})

Почему? Представьте, что пользователь вводит .* в качестве своего имени пользователя. Это будет соответствовать всем именам пользователей, позволяя войти в систему, просто угадав пароль любого пользователя.

5 голосов
/ 30 апреля 2016

Предположим, вы хотите выполнить поиск по «столбцу» в «Таблице» и хотите выполнить поиск без учета регистра. Лучший и эффективный способ, как показано ниже;

//create empty JSON Object
mycolumn = {};

//check if column has valid value
if(column) {
    mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);

Выше код просто добавляет значение поиска в качестве RegEx и выполняет поиск с нечувствительными критериями, установленными с параметром "i".

Всего наилучшего.

5 голосов
/ 16 октября 2014

Используя Mongoose, это сработало для меня:

var find = function(username, next){
    User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
        if(err) throw err;
        next(null, res);
    });
}
3 голосов
/ 22 ноября 2017

Вы можете использовать Индексы без учета регистра :

В следующем примере создается коллекция без сопоставления по умолчанию, затем добавляется индекс в поле имени с сопоставлением без учета регистра. Международные компоненты для 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
3 голосов
/ 20 мая 2017

Структура агрегации была введена в mongodb 2.2. Вы можете использовать строковый оператор "$ strcasecmp" для сравнения строк без учета регистра. Это более рекомендуется и проще, чем использование регулярных выражений.

Вот официальный документ об операторе команды агрегирования: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp.

2 голосов
/ 01 июня 2018

Для поиска и экранирования переменной:

const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})   

Выход из переменной защищает запрос от атак с помощью '. *' Или другого регулярного выражения.

бежать строка-регулярное выражение

0 голосов
/ 13 декабря 2018

Для любого, кто использует Golang и хочет иметь полнотекстовый поиск с учетом регистра с помощью mongodb и mgo godoc globalsign library .

collation := &mgo.Collation{
    Locale:   "en",
    Strength: 2, 
}


err := collection.Find(query).Collation(collation)
0 голосов
/ 03 июля 2018

Использование RegExp , В случае, если какие-либо другие варианты не работают для вас, RegExp является хорошим вариантом. Это делает строку чувствительной к регистру.

var username = new RegExp("John", "i");

Значение username будет похоже на /John/i.

использовать имя пользователя в запросах, а затем это сделано.

Надеюсь, это сработает и для вас. Всего наилучшего.

0 голосов
/ 11 апреля 2018

Я столкнулся с подобной проблемой, и вот что у меня сработало:

  const flavorExists = await Flavors.findOne({
    'flavor.name': { $regex: flavorName, $options: 'i' },
  });
0 голосов
/ 07 августа 2017

Использование фильтра работает для меня в C #.

string s = "searchTerm";
    var filter = Builders<Model>.Filter.Where(p => p.Title.ToLower().Contains(s.ToLower()));
                var listSorted = collection.Find(filter).ToList();
                var list = collection.Find(filter).ToList();

Он может даже использовать индекс, потому что я считаю, что методы вызываются после возврата, но я еще не проверял это.

Это также позволяет избежать проблемы

var filter = Builders<Model>.Filter.Eq(p => p.Title.ToLower(), s.ToLower());

что mongodb будет думать, что p.Title.ToLower () является свойством и не будет правильно отображаться.

...