определения наличия ключевых слов которые есть в нашей с-ме в пользовательских запросах.
Дано:
Есть N пользователсьских уникальных поисковых запросов.
Есть ключевые слова которые могут являтся тегами/категориями или ключевыми словами из определенной области.
Выполняется запрос вида:
SELECT DISTINCT query
FROM TABLE
WHERE not match(‘huge|regex|with|all|keywords’)
AND not match(‘huge|regex|with|all|keywords’)
-> это дает мне промежуточный результат в котором я могу отфильтровать дальше некоторые другие группы ключевых слов
Одна из таких груп, а точнее составленное такое регулярное выражение будет весить около 100мб.
Вопрос как бы вы подошли к решению такой задачи? Я пробовал разбивать на маленькие регулярные выражения, он т.к. в одном запросе ключевые слова могут повторятся я получаю ложно большее количество совпадений чем вообще есть запросов в с-ме. У меня из идей только пагинироваться по первому запросу а регулярку уже применять к каждой строке например в python, записывая результаты в файл.
Сюда поглядите https://fiddle.clickhouse.com/318ec99d-97e9-4478-84f4-01867e74a4b6 Кажется, что можно hasToken будет лучше, регулярные выражения. А в свете недавно появившегося обратного (inverted) индекса, так и вообще должно быть отлично.
Если количество регекспов фиксированное, то свежепоявившийся regexp_tree Dictionary ваш путь. Но если переменный, то надо выкинуть описанную выше идею с регекспами и взять специализированный инструмент, скажем Manticore. Если же есть веские причины по которым вы это делаете на Clickhouse, то придется делать все тоже самое, что в обычном полнотекстовом поиске, а именно: - токенизатор - леммаризатор - обратный индекс - ранжирование Используя 3 первых искать просто и быстро. Обратный индекс - это отдельная табличка и подзапрос. Ну или новая фича (которая пока не то чтобы особо работает). Однако ранжирование - это тяжелый GROUP BY и вы улетаете на 300-600ms, что катастрофически много по сравнению с мантикоровскими 60ms.
Функции для токенизированич смотрели?
Привет! Посмотрел, насколько я понял что hasToken может проверять только наличие одного токена, т.е. если мне подходит например 1000 слов То я буду делать что-то вроде WHERE hastoken(field, ‘field’) OR hastoken(field, ‘field’) … OR hastoken(field, ‘field’) после чего мне нужно сохранить совпавшие индексы и игнорировать их на следующей пачке таких запросов?
Да, я был не прав, использование hasToken создает больше проблем, чем решает. Вариант с regex вроде как лучше. Если хотите, можете создать issue с просьбой добавить в hasToken возможность множественных needle, и описать вашу задачу как обоснование полезности такой доработки.
Нашел не плохое решение для себя с использованием multiMatchAllIndices, думаю использовать temporary таблицу чтобы сохранить уже сматченные id, посчитал по весу возможного количества ids - по памяти приемлемо. Пачками по 1000 токенов работает быстрее чем match
Обсуждают сегодня