Перейти к основному содержанию
Перейти к основному содержанию

Поиск в ClickStack и Elastic

Поиск в ClickStack и Elastic

ClickHouse — это нативный SQL-движок, изначально спроектированный для высокопроизводительных аналитических нагрузок. В отличие от него, Elasticsearch предоставляет SQL-подобный интерфейс, который транслирует SQL в базовый Elasticsearch query DSL — то есть SQL не является для него языком первого класса, и функциональный паритет ограничен.

ClickHouse не только полностью поддерживает SQL, но и расширяет его набором функций, ориентированных на наблюдаемость, таких как argMax, histogram и quantileTiming, которые упрощают выполнение запросов к структурированным логам, метрикам и трейсам.

Для простой работы с логами и трейсами HyperDX предоставляет синтаксис в стиле Lucene для интуитивно понятной текстовой фильтрации по запросам вида поле-значение, диапазонам, шаблонам с подстановками (wildcards) и другим условиям. Это сопоставимо с синтаксисом Lucene в Elasticsearch и элементами Kibana Query Language.

Поиск

Интерфейс поиска HyperDX поддерживает этот привычный синтаксис, но «за кулисами» транслирует его в эффективные выражения SQL WHERE, делая работу привычной для пользователей Kibana и при этом позволяя использовать мощь SQL при необходимости. Это даёт возможность задействовать весь спектр функций строкового поиска, функций сходства и функций работы с датой и временем в ClickHouse.

SQL

Ниже мы сравниваем языки запросов в стиле Lucene в ClickStack и Elasticsearch.

Синтаксис поиска ClickStack vs Elasticsearch query string

И HyperDX, и Elasticsearch предоставляют гибкие языки запросов для интуитивной фильтрации логов и трассировок. Хотя query string в Elasticsearch тесно интегрирован с его DSL и движком индексирования, HyperDX поддерживает синтаксис, вдохновлённый Lucene, который под капотом транслируется в ClickHouse SQL. В таблице ниже показано, как распространённые шаблоны поиска работают в обеих системах, с акцентом на сходство синтаксиса и различия в выполнении на стороне бэкенда.

FeatureHyperDX SyntaxElasticsearch SyntaxComments
Free text searcherrorerrorСовпадения по всем индексированным полям; в ClickStack это переписывается в SQL-запрос по нескольким полям с использованием ILIKE.
Field matchlevel:errorlevel:errorИдентичный синтаксис. HyperDX сопоставляет точные значения полей в ClickHouse.
Phrase search"disk full""disk full"Заключённый в кавычки текст соответствует точной последовательности; ClickHouse использует сравнение строк на равенство или ILIKE.
Field phrase matchmessage:"disk full"message:"disk full"Транслируется в SQL ILIKE или точное совпадение.
OR conditionserror OR warningerror OR warningЛогическое ИЛИ терминов; обе системы нативно поддерживают это.
AND conditionserror AND dberror AND dbОбе системы транслируют в пересечение; различий в пользовательском синтаксисе нет.
NegationNOT error or -errorNOT error or -errorПоддерживается одинаково; HyperDX конвертирует в SQL NOT ILIKE.
Grouping(error OR fail) AND db(error OR fail) AND dbСтандартная булева группировка в обеих системах.
Wildcardserror* or *fail*error*, *fail*HyperDX поддерживает начальные и конечные подстановочные символы; в Elasticsearch начальные подстановки по умолчанию отключены из соображений производительности. Подстановки внутри термов не поддерживаются, например f*ail. Подстановки должны применяться вместе с указанием поля.
Ranges (numeric/date)duration:[100 TO 200]duration:[100 TO 200]HyperDX использует SQL BETWEEN; Elasticsearch разворачивает в диапазонные запросы. Неограниченные * в диапазонах не поддерживаются, например duration:[100 TO *]. При необходимости используйте Unbounded ranges ниже.
Unbounded ranges (numeric/date)duration:>10 or duration:>=10duration:>10 or duration:>=10HyperDX использует стандартные SQL-операторы.
Inclusive/exclusiveduration:{100 TO 200} (exclusive)SameФигурные скобки обозначают исключающие границы. * в диапазонах не поддерживается, например duration:[100 TO *].
Exists checkN/A_exists_:user or field:*_exists_ не поддерживается. Используйте LogAttributes.log.file.path: * для столбцов типа Map, например LogAttributes. Для корневых столбцов требуется их существование, и они будут иметь значение по умолчанию, если не были включены в событие. Для поиска значений по умолчанию или отсутствующих столбцов используйте тот же синтаксис, что и в Elasticsearch: ServiceName:* или ServiceName != ''.
Regexmatch functionname:/joh?n(ath[oa]n)/В настоящее время не поддерживается в синтаксисе Lucene. Пользователи могут использовать SQL и функцию match или другие функции поиска по строкам.
Fuzzy matcheditDistance('quikc', field) = 1quikc~В настоящее время не поддерживается в синтаксисе Lucene. В SQL можно использовать функции расстояния, например editDistance('rror', SeverityText) = 1, или другие функции сходства.
Proximity searchNot supported"fox quick"~5В настоящее время не поддерживается в синтаксисе Lucene.
Boostingquick^2 foxquick^2 foxВ настоящее время не поддерживается в HyperDX.
Field wildcardservice.*:errorservice.*:errorВ настоящее время не поддерживается в HyperDX.
Escaped special charsEscape reserved characters with \SameДля зарезервированных символов требуется экранирование.

Отличия между существующими и отсутствующими значениями

В отличие от Elasticsearch, где поле может быть полностью опущено в событии и, следовательно, действительно «не существовать», в ClickHouse требуется наличие всех столбцов, определённых в схеме таблицы. Если поле не указано в событии при вставке:

  • Для полей типа Nullable ему будет присвоено значение NULL.
  • Для полей, не допускающих NULL (это поведение по умолчанию), оно будет заполнено значением по умолчанию (часто пустой строкой, 0 или эквивалентом).

В ClickStack мы используем второй вариант, так как тип Nullable не рекомендуется.

Такое поведение означает, что проверка, «существует» ли поле в смысле Elasticsearch, напрямую не поддерживается.

Вместо этого пользователи могут использовать field:* или field != '' для проверки наличия непустого значения. Таким образом, невозможно различить действительно отсутствующие и явно пустые поля.

На практике это различие редко приводит к проблемам для сценариев наблюдаемости, но его важно учитывать при переносе запросов между системами.