У меня есть вложенное поле с именем items.productName, в котором я хочу проверить, содержит ли название продукта определенную строку.
SELECT * FROM test WHERE hasAny(items.productName,['Samsung'])
Это работает, только если название продукта — Samsung.
Я пробовал присоединиться к массиву
SELECT
*
FROM test
ARRAY JOIN items
WHERE items.productName LIKE '%Samsung%'
Это работает, но очень медленно (~ 1 сек на 5 миллионов записей)
Есть ли способ выполнить как в hasAny?
Вы можете добиться этого, используя функцию arrayFilter. Документы ClickHouse
Запрос
Select * from test where arrayFilter(x -> x LIKE '%Samsung%', items.productName) != []
Если вы не используете != [], вы получите сообщение об ошибке «DB::Exception: недопустимый тип массива (строка) столбца для фильтра. Должен быть вариант UInt8 или Nullable (UInt8) или Const».
Лучшим подходом к этому было бы использование функции
arrayExists
:WHERE arrayExists(x -> x LIKE '%Samsung%', items.productName)
. Это избавляет от необходимости сравнивать с пустым массивом и позволяет ClickHouse оптимизировать предложение путем короткого замыкания, когда найдено первое совпадающее значение массива, вместо того, чтобы перебирать весь массив.