Встроенные в Postgres функции текстового поиска могут помочь здесь.Но вам нужно будет добавить второй столбец в таблицу A, чтобы помочь его проиндексировать.Вам также необходимо знать язык каждой строки в таблице A.
Пример запроса.
postgres=# select to_tsvector('english', 'Big cats eat fish on Mondays.')
@@ phraseto_tsquery('english', 'eat fish on monday') as query;
query
-------
t
Обратите внимание, что множественное число и заглавные буквы Mondays
не остановили совпадение.
Используйте функцию to_tsvector
для создания проанализированной формы вашего контента, которую вы можете использовать для индекса GIN.
postgres=# select to_tsvector('english', 'Big cats eat fish on Mondays.');
to_tsvector
---------------------------------------------
'big':1 'cat':2 'eat':3 'fish':4 'monday':6
Обратите внимание, как to_tsvector
нормализует строку (меняется на строчные буквы)удаление знаков препинания, удаление множественного числа и удаление слов с низким значением, таких как «вкл»).Это означает, что «есть рыбу, если понедельник» также будет соответствовать (так как «если» также слово с низким значением).Поэтому вам нужно будет добавить вторую проверку, используя оператор LIKE
, если вы хотите только точное совпадение.Но это будет выполняться гораздо реже, чем без индекса tsvector
GIN.
Таким образом, ваш запрос теперь будет выглядеть так:
SELECT subcontent, content
FROM A
JOIN B ON (
A.tsv_content @@ phraseto_tsquery(B.lang, B.subcontent)
AND content LIKE '%' || subcontent || '%'
);
NB.phraseto_tsquery
требуется 9,6 +