MongoDB и С#: поиск нечувствительности к регистру
Я использую MongoDB и драйвер С# для MongoDB.
Недавно я обнаружил, что все запросы в MongoDB чувствительны к регистру. Как я могу сделать поиск без учета регистра?
Я нашел один способ сделать это:
Query.Matches(
"FirstName",
BsonRegularExpression.Create(new Regex(searchKey,RegexOptions.IgnoreCase)));
Ответы
Ответ 1
Самый простой и безопасный способ - Linq
:
var names = namesCollection.AsQueryable().Where(name =>
name.FirstName.ToLower().Contains("hamster"));
Как объяснено в tutorial ToLower
, ToLowerInvariant
, ToUpper
и ToUpperInvariant
все выполняют совпадения в случае нечувствительным способом. После этого вы можете использовать все поддерживаемые строковые методы, такие как Contains
или StartsWith
.
В этом примере будут созданы:
{
"FirstName" : /hamster/is
}
Опция i
делает регистр нечувствительным.
Ответ 2
Я только что реализовал это намного проще, чем любые другие предложения. Однако я понимаю, из-за возраста этого вопроса, эта функция, возможно, не была доступна в то время.
Используйте параметры конструктора Bson Regular Expression, чтобы передать в случае нечувствительности. Я просто посмотрел на исходный код и обнаружил, что "я" - это все, что вам нужно. Например.
var regexFilter = Regex.Escape(filter);
var bsonRegex = new BsonRegularExpression(regexFilter, "i");
Query.Matches("MyField", bsonRegex);
Вам не нужно дважды записывать записи для поиска.
Ответ 3
попробуйте использовать что-то вроде этого:
Query.Matches("FieldName", BsonRegularExpression.Create(new Regex(searchKey, RegexOptions.IgnoreCase)))
Ответ 4
Вам, вероятно, придется хранить поле дважды, один раз с его реальным значением, и снова во всех строчных. Затем вы можете запросить версию с нижним регистром для поиска без учета регистра (не забудьте также ввести строчную строку запроса).
Этот подход работает (или необходим) для многих систем баз данных и должен работать лучше, чем методы на основе регулярных выражений (по крайней мере, для префикса или точного соответствия).
Ответ 5
Как ответил i3arnon, вы можете использовать Queryable, чтобы делать нечувствительное к регистру сравнение/поиск. Я узнал, что я не мог использовать метод string.Equals(), потому что он не поддерживается. Если вам нужно сделать сравнение, Contains(), к сожалению, не подходит, что заставило меня изо всех сил пытаться решить какое-то решение.
Для тех, кто хочет выполнить сравнение строк, просто используйте == вместо .Equals().
код:
var names = namesCollection.AsQueryable().Where(name =>
name.FirstName.ToLower() == name.ToLower());
Ответ 6
Если кому-то еще интересно, используя fluent-mongo, вы можете использовать Linq для запроса:
public User FindByEmail(Email email)
{
return session.GetCollection<User>().AsQueryable()
.Where(u => u.EmailAddress.ToLower() == email.Address.ToLower()).FirstOrDefault();
}
Это приводит к правильному JS-запросу. К сожалению, String.Equals() еще не поддерживается.
Ответ 7
Способ сделать это - использовать класс MongoDB.Bson.BsonJavaScript, как показано ниже.
store.FindAs<Property>(Query.Where(BsonJavaScript.Create(string.Format("this.City.toLowerCase().indexOf('{0}') >= 0", filter.City.ToLower()))));
Ответ 8
Вы также можете использовать встроенные фильтры MongoDB. Это может облегчить использование некоторых методов mongo.
var filter = Builders<Model>.Filter.Where(p => p.PropertyName.ToLower().Contains(s.ToLower()));
var list = collection.Find(filter).Sort(mySort).ToList();