С C # 4.0 отражение не требуется, поскольку DLR может вызывать его с использованием типов времени выполнения. Так как использование библиотеки DLR представляет собой боль динамически (вместо кода генерации компилятора C # для вас), open source framework Dynamitey (.net standard 1.5) дает вам простой кэшированный доступ во время выполнения те же вызовы, которые генерирует компилятор для вас.
var name = InvokeMemberName.Create;
Dynamic.InvokeMemberAction(this, name("GenericMethod", new[]{myType}));
var staticContext = InvokeContext.CreateStatic;
Dynamic.InvokeMemberAction(staticContext(typeof(Sample)), name("StaticMethod", new[]{myType}));
Вы можете использовать regex .
В вашем примере это будет:
db.stuff.find( { foo: /^bar$/i } );
Я должен сказать, хотя, может быть, вы могли бы просто (или вверху) значение на пути, а не приносить дополнительную стоимость каждый раз, когда вы его находите. Очевидно, что это не будет работать для имен людей и т. Д., Но, может быть, таких случаев, как теги.
Mongo (текущая версия 2.0.0) не разрешает поиск по регистровым полям с индексированными полями - см. их документацию . Для неиндексированных полей регулярные выражения, перечисленные в других ответах, должны быть точными.
Предположим, что вы хотите найти «столбец» в «Таблице», и вы хотите, чтобы поиск в insensstive. Лучший и эффективный способ: ниже
//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 и выполняется поиск с критериями insensitve, установленными с опцией «i».
Все лучший.
Они были протестированы для поиска строк
{'_id': /.*CM.*/} ||find _id where _id contains ->CM
{'_id': /^CM/} ||find _id where _id starts ->CM
{'_id': /CM$/} ||find _id where _id ends ->CM
{'_id': /.*UcM075237.*/i} ||find _id where _id contains ->UcM075237, ignore upper/lower case
{'_id': /^UcM075237/i} ||find _id where _id starts ->UcM075237, ignore upper/lower case
{'_id': /UcM075237$/i} ||find _id where _id ends ->UcM075237, ignore upper/lower case
Как вы можете видеть в документах mongo - поскольку индекс версии 3.2 $text
по умолчанию не чувствителен к регистру: https://docs.mongodb.com/manual/core/index-text/#text-index -фаза-нечувствительность
Создайте текстовый индекс и используйте текстовый оператор в вашем запросе .
Использование фильтра работает для меня в 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 () является свойством и не будет правильно отображаться.
Используя Mongoose, это сработало для меня:
var find = function(username, next){
User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
if(err) throw err;
next(null, res);
});
}
.toLowerCase()
, если вы указываете флаг, нечувствительный к регистру i
?
– k00k
1 July 2015 в 15:01
Одна важная вещь, которую следует иметь в виду при использовании запроса на основе Regex. Когда вы делаете это для системы входа в систему, удаляет каждый отдельный символ , который вы ищете, и не забывайте ^ и $ операторов. Lodash имеет приятную функцию для этого , если вы уже используете его:
db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})
Почему? Представьте, что пользователь вводит .*
в качестве своего имени пользователя. Это будет соответствовать всем именам пользователей, что позволит войти в систему, просто угадывая пароль пользователя.
new RegExp("^" + req.params.term.toLowerCase(), "i")
также отлично работает
– Tahir Yasin
29 March 2017 в 15:43
Для поиска переменной и ее экранирования:
const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})
Экранирование переменной защищает запрос от атак с помощью.. * или другого регулярного выражения.
Использовать RegExp. Если какие-либо другие параметры не работают для вас, RegExp является хорошим вариантом. Это делает строковый регистр чувствительным.
var username = "John";
var uname = new RegExp(username, "i");
Значение uname
будет похоже на /John/i
.
использовать uname в запросах вместо имени пользователя, а затем его выполнить.
Надеюсь, это сработает и для вас. Все лучшее.
Вы можете использовать индексы, нечувствительные к регистру:
В следующем примере создается коллекция без сортировки по умолчанию, а затем добавляется индекс в поле имени с учетом нечувствительности к регистру. Международные компоненты для 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
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
– Mohd Belal
12 April 2018 в 11:56
Имейте в виду, что предыдущий пример:
db.stuff.find( { foo: /bar/i } );
приведет к тому, что каждая запись, содержащая бар, будет соответствовать запросу (bar1, barxyz, openbar), это может быть очень опасно для поиска имени пользователя на auth function ...
Возможно, вам потребуется сопоставить только поисковый запрос, используя соответствующий синтаксис regexp как:
db.stuff.find( { foo: /^bar$/i } );
См. http: // www .regular-expressions.info / для синтаксической справки по регулярным выражениям
UPDATE:
Исходный ответ устарел. Mongodb теперь поддерживает расширенный полнотекстовый поиск со многими функциями.
ОРИГИНАЛЬНЫЙ ОТВЕТ:
Следует отметить, что поиск с регистрозависимым регистром нечувствителен / i означает, что mongodb не может искать по индексу, поэтому запросы к большим наборам данных могут занять много времени.
Даже с небольшими наборами данных это не очень эффективно. Вы делаете гораздо больший бит процессора, чем ваши ордера на запрос, что может стать проблемой, если вы пытаетесь достичь масштаба.
. В качестве альтернативы вы можете хранить заглавную копию и искать ее. Например, у меня есть таблица User, у которой есть имя пользователя, которое является смешанным случаем, но идентификатор является заглавной копией имени пользователя. Это гарантирует, что дублирование, чувствительное к регистру, невозможно (иметь возможность «Foo» и «foo» не будет разрешено), и я могу выполнить поиск по id = username.toUpperCase (), чтобы получить поиск по имени пользователя без регистра.
Если ваше поле большое, например тело сообщения, дублирование данных, вероятно, не является хорошим вариантом. Я считаю, что использование альтернативного индексатора, такого как Apache Lucene, является лучшим вариантом в этом случае.
Структура агрегирования была введена в mongodb 2.2. Вы можете использовать строковый оператор «$ strcasecmp», чтобы сделать нечувствительное к регистру сравнение строк. Это более рекомендуется и проще, чем при использовании регулярного выражения.
Вот официальный документ оператора оператора агрегации: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/# exp._S_strcasecmp .
db.zipcodes.find({city : "NEW YORK"}); // Case-sensitive
db.zipcodes.find({city : /NEW york/i}); // Note the 'i' flag for case-insensitivity
Я создал простой Func для нечувствительного к регистру regex, который я использую в своем фильтре.
private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) =>
BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));
Затем вы просто фильтруете поле в следующем виде.
db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();
Лучший способ заключается в выборе вашего языка при создании обертки модели для ваших объектов, попробуйте выполнить метод save () через набор полей, которые вы будете искать, которые также индексируются; эти группы полей должны иметь строчные копии, которые затем используются для поиска.
Каждый раз, когда объект сохраняется снова, нижние значения затем проверяются и обновляются с любыми изменениями основных свойств. Это сделает так, чтобы вы могли эффективно искать, но скрыть дополнительную работу, необходимую для обновления полей lc каждый раз.
В нижнем регистре могут быть хранилище объектов с ключом: значение или просто имя поля с префикс lc_. Я использую второй, чтобы упростить запрос (запросы на глубинные объекты могут иногда заблуждаться).
Примечание: вы хотите индексировать поля lc_, а не основные поля, на которых они основаны.
В соответствии с Mongodb 3.4 вы должны использовать индекс индексирования без учета регистра. Это самый быстрый способ сделать поиск без учета регистра данных по наборам данных большего размера. Я лично отправил по электронной почте одного из основателей, чтобы получить эту работу, и он сделал это! (Это была проблема JIRA как 5 лет, и многие просили эту функцию). Вот как это работает:
Индекс чувствительности к регистру производится путем задания сопоставления с силой 1 или 2. Вы можете создать индекс без учета регистра следующим образом:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
Или вы можете сделать это для всей коллекции по умолчанию при создании базы данных следующим образом:
db.createCollection("Cities",{collation: {locale: "en",strength:2}});
И использовать ее следующим образом:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
Это будет return "New York", "new york" и т. д.
В качестве альтернативы вы можете сделать все индексы по умолчанию, когда вы создаете такую коллекцию:
db.createCollection("cities",{collation:{locale: "en", strength: 2}});
Преимущество этого метода - значительно повысить эффективность и скорость работы с большими наборами данных.
Для получения дополнительной информации: https://jira.mongodb.org/browse/SERVER-90 , https://docs.mongodb.com/manual/reference/collation/
TL; DR
Не использовать RegExp
Перейти к естественному и использовать встроенное индексирование mongodb, поиск
db.articles.insert(
[
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
]
)
Необходимо создать индекс в зависимости от того, какое поле TEXT вы хотите искать, без запроса индексирования будет чрезвычайно медленным
db.articles.createIndex( { subject: "text" } )
db.articles.find( { $text: { $search: "coffee",$caseSensitive :true } } ) //FOR SENSITIVITY
db.articles.find( { $text: { $search: "coffee",$caseSensitive :false } } ) //FOR INSENSITIVITY
Я столкнулся с подобной проблемой, и это сработало для меня:
const flavorExists = await Flavors.findOne({
'flavor.name': { $regex: flavorName, $options: 'i' },
});