Как лучше в EF Core 9 произвести поиск совпадений на русском и без учета регистра?

Ссылка скопирована
1 ответ

Использую SQLite.
По вводным: если поиск на английском то все хорошо. Но вот на русском поиск совпадений чуствителен к регистру.
Сейчас ситуация такая: то что я пытался и не работает:

Result = await _context.Podcasts //1) .Where(p => p.Title.StartsWith(value)) //2) .Where(p => p.Title.ToLower().StartsWith(value.ToLower())) //3) .Where(p => EF.Functions.Like(p.Title, $"{value}%")) //4) .Where(p => EF.Functions.Like(p.Title.ToLower(), $"{value.ToLower()}%")) //5) .FromSqlRaw("SELECT * FROM Podcasts WHERE LOWER(Title) LIKE LOWER({0})", $"{value}%") .ToListAsync();
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Юрий Linux Ответ

В EF Core 9 поиск по русскому тексту без учёта регистра лучше делать не через ToLower() в запросе, а через правильную collation/сравнение на стороне базы. Иначе можно потерять индексы и получить медленный поиск на больших таблицах.

Если база PostgreSQL, используйте ILIKE:

var q = await db.Items
    .Where(x => EF.Functions.ILike(x.Title, $"%{search}%"))
    .ToListAsync();

var q = await db.Items .Where(x => EF.Functions.ILike(x.Title, $"%{search}%")) .ToListAsync();

Если SQL Server, задайте подходящую collation:

var q = await db.Items
    .Where(x => EF.Functions.Collate(x.Title, "Cyrillic_General_CI_AI").Contains(search))
    .ToListAsync();

var q = await db.Items .Where(x => EF.Functions.Collate(x.Title, "Cyrillic_General_CI_AI").Contains(search)) .ToListAsync();

CI означает case-insensitive, AI — accent-insensitive. Подбирайте collation под вашу базу и язык данных. Для русского обычно важен регистр, буквы ё/е и сортировка.

Для MySQL/MariaDB аналогично выбирайте collation у поля или в запросе, например utf8mb4_unicode_ci или более подходящий вариант для вашей версии.

Если нужен полнотекстовый поиск, не пытайтесь заменить его Contains. Для нормального поиска по словам, морфологии и ранжированию лучше использовать full-text index, PostgreSQL tsvector, Elasticsearch/OpenSearch или отдельный поисковый движок.

Итог: для простого поиска используйте collation/ILIKE, а не ToLower(). Для больших объёмов и русского морфологического поиска проектируйте отдельный полнотекстовый индекс.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно