Как выполнить запрос в MongoDB с использованием ‘like’
Я хочу выполнить запрос, аналогичный SQL-оператору like:
SELECT * FROM users WHERE name LIKE '%m%'
Как можно добиться того же в MongoDB? Я не могу найти оператор для ‘like’ в документации.
Реализация функциональности SQL LIKE в MongoDB
Для реализации функциональности SQL LIKE в MongoDB необходимо использовать оператор $regex, который предоставляет возможности сопоставления шаблонов, аналогичные SQL LIKE. Для конкретного запроса SELECT * FROM users WHERE name LIKE '%m%' в MongoDB вы бы использовали db.users.find({name: {$regex: 'm'}}), где шаблон регулярного выражения 'm' без привязок ведет себя как шаблон с подстановочными знаками SQL %m%.
Содержание
- Понимание различий между SQL LIKE и сопоставлением шаблонов в MongoDB
- Использование оператора $regex для базового сопоставления шаблонов
- Перевод шаблонов SQL LIKE в регулярные выражения MongoDB
- Параметры чувствительности к регистру
- Рекомендации по производительности
- Альтернативные подходы
- Практические примеры
Понимание различий между SQL LIKE и сопоставлением шаблонов в MongoDB
MongoDB не поддерживает прямой оператор в стиле SQL LIKE, но предоставляет мощные возможности сопоставления шаблонов через регулярные выражения с помощью оператора $regex. Этот подход предлагает даже большую гибкость, чем SQL LIKE, при сохранении аналогичной функциональности для базовых потребностей в сопоставлении шаблонов.
Ключевое отличие заключается в том, что SQL LIKE использует простые символы-подстановки:
%соответствует любой последовательности из нуля или более символов_соответствует любому одиночному символу
В то время как $regex в MongoDB использует полный синтаксис регулярных выражений, который может обрабатывать более сложные шаблоны, но требует понимания основ регулярных выражений.
Использование оператора $regex для базового сопоставления шаблонов
Оператор $regex является основным инструментом MongoDB для операций сопоставления шаблонов. Он позволяет искать шаблоны внутри строковых полей с использованием регулярных выражений.
Базовый синтаксис:
db.collection.find({
field_name: {
$regex: 'pattern',
$options: 'options'
}
})
Для вашего конкретного примера поиска имен, содержащих ‘m’, самый простой подход:
db.users.find({
name: {
$regex: 'm'
}
})
Это эквивалентно SQL WHERE name LIKE '%m%', потому что:
- Отсутствие привязок (^ или $) означает, что шаблон может появиться в любой части строки
- Движок регулярных выражений автоматически находит совпадение, если ‘m’ встречается где-либо в имени
Перевод шаблонов SQL LIKE в регулярные выражения MongoDB
Вот как переводить распространенные шаблоны SQL LIKE в регулярные выражения MongoDB:
| Шаблон SQL LIKE | Эквивалент MongoDB | Описание |
|---|---|---|
LIKE '%m%' |
{$regex: 'm'} |
Шаблон встречается в любом месте |
LIKE 'm%' |
{$regex: '^m'} |
Шаблон начинается с ‘m’ |
LIKE '%m' |
{$regex: 'm$'} |
Шаблон заканчивается на ‘m’ |
LIKE '_m_' |
{$regex: '.m.'} |
Один символ до и после |
LIKE 'a%b' |
{$regex: '^ab'} |
Начинается с ‘ab’ |
LIKE '%a%b% |
{$regex: 'a.*b'} |
Содержит ‘a’, затем позже ‘b’ |
Для более сложных шаблонов можно использовать полный синтаксис регулярных выражений:
// Несколько шаблонов с ИЛИ
db.users.find({
name: {
$regex: 'm|n|p' // содержит m, n или p
}
})
// Классы символов
db.users.find({
name: {
$regex: '[aeiou]' // содержит любую гласную
}
})
Параметры чувствительности к регистру
По умолчанию запросы регулярных выражений в MongoDB чувствительны к регистру. Для достижения регистронезависимого сопоставления, аналогичного SQL LIKE (который часто не чувствителен к регистру в зависимости от конфигурации базы данных), у вас есть несколько вариантов:
Метод 1: Использование параметра $options
db.users.find({
name: {
$regex: 'm',
$options: 'i' // i = нечувствительность к регистру
}
})
Метод 2: Использование встроенных флагов регулярных выражений
db.users.find({
name: {
$regex: '(?i)m' // (?i) включает режим нечувствительности к регистру
}
})
Метод 3: Использование сортировки (collation) для лучшей производительности
Согласно документации MongoDB, для регистронезависимых поиск рекомендуется создавать индексы с нечувствительностью к регистру со степенью сортировки 1 или 2 для лучшей производительности:
db.users.createIndex(
{ name: 1 },
{ collation: { strength: 2 } }
)
Затем запрос выполняется так:
db.users.find({
name: { $regex: 'm' }
})
Рекомендации по производительности
При работе с шаблонами регулярных выражений в MongoDB производительность является ключевым фактором:
Использование индексов
- Простые префиксы: Шаблоны вроде
^mмогут эффективно использовать индексы - Сложные шаблоны: Шаблоны без префикса (как
m) или суффиксные шаблоны не могут эффективно использовать индексы - Чувствительность к регистру: Согласно документации MongoDB, “Индексы, не чувствительные к регистру, не улучшают производительность для запросов $regex, так как оператор $regex не осведомлен о сортировке (collation) и поэтому не может использовать такие индексы.”
Советы по оптимизации производительности
- Используйте привязанные шаблоны, когда возможно:
^patternилиpattern$могут использовать индексы - Избегайте ведущих подстановочных знаков: Шаблоны вроде
%patternне могут использовать индексы - Рассмотрите текстовый поиск: Для полнотекстового поиска используйте оператор
$textвместо регулярных выражений - Предварительно компилируйте регулярные выражения: В языках программирования компилируйте шаблоны регулярных выражений один раз и используйте повторно
Когда регулярные выражения могут не быть лучшим выбором
Как упоминается в некоторых источниках, регулярные выражения могут быть вычислительно затратными для больших наборов данных. Рассмотрите альтернативы, такие как:
- Хранение нормализованных версий полей (в нижнем регистре для регистронезависимых поиска)
- Использование фреймворка агрегации MongoDB для сложного сопоставления шаблонов
- Реализация решений индексации поиска, таких как MongoDB Atlas Search
Альтернативные подходы
Метод 1: Использование $expr в агрегации
Для более сложного сопоставления шаблонов внутри конвейеров агрегации:
db.users.aggregate([
{
$match: {
$expr: {
$regexMatch: {
input: '$name',
regex: 'm'
}
}
}
}
])
Метод 2: Использование строковых операторов
Для простого сопоставления подстрок без использования регулярных выражений:
// Содержит
db.users.find({
name: { $exists: true, $ne: null, $not: { $size: 0 } }
}).filter(doc => doc.name.includes('m'))
Примечание: Этот подход требует фильтрации на стороне клиента и может быть неэффективным для больших наборов данных.
Метод 3: Использование индексов текстового поиска
Для возможностей полнотекстового поиска:
// Создание индекса текстового поиска
db.users.createIndex({ name: "text" })
// Поиск
db.users.find({
$text: { $search: "m" }
})
Практические примеры
Пример 1: Базовое сопоставление шаблонов
// SQL: SELECT * FROM users WHERE name LIKE '%john%'
// MongoDB:
db.users.find({
name: { $regex: 'john' }
})
// С нечувствительностью к регистру:
db.users.find({
name: {
$regex: 'john',
$options: 'i'
}
})
Пример 2: Шаблон в начале
// SQL: SELECT * FROM users WHERE name LIKE 'john%'
// MongoDB:
db.users.find({
name: { $regex: '^john' }
})
Пример 3: Шаблон в конце
// SQL: SELECT * FROM users WHERE name LIKE '%smith'
// MongoDB:
db.users.find({
name: { $regex: 'smith$' }
})
Пример 4: Несколько символов с подстановочными знаками
// SQL: SELECT * FROM users WHERE name LIKE 'j_nn'
// MongoDB:
db.users.find({
name: { $regex: '^j.n$' }
})
Пример 5: Сложный шаблон с логикой ИЛИ
// SQL: SELECT * FROM users WHERE name LIKE '%john%' OR name LIKE '%mary%'
// MongoDB:
db.users.find({
name: { $regex: 'john|mary' }
})
Пример 6: Сопоставление шаблона email
// SQL: SELECT * FROM users WHERE email LIKE '%@example.com'
// MongoDB:
db.users.find({
email: { $regex: '@example\\.com$' }
})
Источники
- MongoDB $regex - Руководство по базе данных
- Как выполнять запросы MongoDB с “like” - Stack Overflow
- Пример запроса MongoDB с “like” - Spark By Examples
- Сопоставление шаблонов MongoDB: использование Regex для запросов “like” - W3Resource
- Как выполнять запросы MongoDB с “like”? - GeeksforGeeks
- MongoDB - Regex - GeeksforGeeks
- MongoDB - Регулярные выражения - Tutorialspoint
Заключение
MongoDB предоставляет надежные возможности сопоставления шаблонов через оператор $regex, которые могут эффективно заменять функциональность SQL LIKE. Ключевые выводы включают:
- Используйте
$regex: 'pattern'для базового сопоставления шаблонов, эквивалентногоLIKE '%pattern%' - Используйте привязки
^и$для конкретных совпадений в начале/конце - Используйте
$options: 'i'для регистронезависимого поиска - Учитывайте последствия для производительности, особенно с ведущими подстановочными знаками, которые не могут использовать индексы
- Рассмотрите альтернативные подходы, такие как индексы текстового поиска для сложных требований к поиску
- Синтаксис регулярных выражений более мощный, чем SQL LIKE, но требует понимания основ регулярных выражений
Для вашего конкретного запроса SELECT * FROM users WHERE name LIKE '%m%' эквивалент в MongoDB - это просто db.users.find({name: {$regex: 'm'}}), который предоставляет ту же функциональность, предлагая дополнительную гибкость для более сложных потребностей в сопоставлении шаблонов.