⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.

Regular expressions in Manticore Search

В этой статье мы расскажем о регулярных выражениях и о том, как их можно использовать в Manticore Search
Если говорить о поиске текста, самым простым является сравнение строк. И поисковая строка, и документ или поле должны быть полностью одинаковыми. Следующий метод поиска текста — выполнение простого сопоставления шаблона, которое позволяет искать поисковую строку как часть поля. Такое простое сопоставление шаблона может использовать базовые операторы, такие как подстановочные знаки, где метасимволы * или % означают «соответствует любым символам». В базах данных это обычно реализуется оператором LIKE, например:

SELECT * FROM mytable WHERE title LIKE '%and%'

будет находить строки с заголовками, содержащими буквальный подстроку 'and'.

Регулярные выражения работают с обычным текстом, как и LIKE, но они предоставляют мощный набор метасимволов‑операторов, позволяющих создавать сложные шаблоны сопоставления. Шаблон regex работает на уровне символов и может сопоставлять буквы, цифры и другие символы, либо по буквальному значению (например, /abc/ будет соответствовать abc), либо по типу класса, например \w будет соответствовать [A‑Aa‑z0‑9_]. Шаблон также может включать логическое or, как abc|xyz, квантификации — ? обозначает ноль или один вхождений предшествующего символа или подстановочного знака (метасимвол .).

В отличие от regex, полнотекстовый поиск не работает с обычным текстом, а разбирает тексты и разбивает их на слова. Полнотекстовый поиск не пытается найти шаблон в строке, а ищет в наборе слов. Хотя регулярные выражения могут находить и выделять слова, у них есть естественные ограничения, так как они не могут выполнять простые булевы поиски вроде abc -xyz или работать с морфологией. Некоторые возможности, присутствующие в регулярных выражениях, также доступны в полнотекстовом поиске, например операторы start/end. Некоторые работают иначе. Например, wildcards в regex могут заменять любое количество символов, тогда как в полнотекстовом поиске подстановочные знаки могут расширяться только в пределах слова или могут полностью заменять слово.

Регулярные выражения были доступны до настоящего времени как опциональная функция во время индексации через regexp_filter . Регекс можно использовать для преобразования строк, что иначе было бы сложнее реализовать обычными опциями токенизации. Например, лигатуру 'ae' можно заменить на 'a' или заменить шаблон вроде XX" на XX inch.

Начиная с версии 2.7.5 регулярные выражения можно использовать в SELECT‑запросах с помощью функции REGEX() . REGEX() принимает строку во входных данных, которая может поступать из строкового атрибута или свойства JSON‑строки, а также регулярное выражение, которое будет проверено против входных данных. REGEX работает только с значениями атрибутов, её нельзя использовать для полнотекстовых полей.

Зачем нужна функция REGEX, если мы уже можем индексировать тексты в полнотекстовых полях?
Во-первых, у нас могут быть строки (либо как атрибуты, либо в JSON‑данных), к которым необходимо применить поисковый шаблон, не связанный напрямую с полнотекстовым сопоставлением. Например, метаданные могут содержать некоторые коды, и мы хотим сузить поиск, оставив только записи, где эти коды начинаются с цифры, например:

SELECT * FROM myindex WHERE MATCH('something') AND REGEX(json_attr.code, "^\d\w+")

Еще одна причина — в настоящее время текстовые данные из JSON‑атрибутов не индексируются как полнотекстовые. Если нам нужно выполнять над некоторыми строковыми свойствами более сложные операции, чем простое сравнение, нам придётся перенести их в полнотекстовое поле (и использовать ZONEs для ограничения сопоставления определёнными метками) или в несколько полнотекстовых полей (что может стать проблемой, если количество этих свойств варьируется).

Например, метаданные продукта, заключённые в объект JSON, могут содержать свойство со списком совместимых устройств этого продукта. С помощью REGEX мы можем создать шаблон, который будет соответствовать нужному нам продукту или даже серии этого продукта:

SELECT * FROM myindex WHERE MATCH('red case') AND REGEX(json_attr.compatible_devices, "Galaxy S[7|8|9]")

В некоторых случаях REGEX() может быть незаменима. Дайте нам знать, если вы находите её полезной!

Установить Manticore Search

Установить Manticore Search