Я работаю над плохим, но хорошо для нас , полнотекстовый поиск с использованием только PSQL в Firebird. Я постараюсь максимально упростить, сосредоточившись на моей проблеме:
Подводя итог, это словарь таблицы:
SELECT * FROM FTS_KEYWORDS
ID | KEYWORD
----+-----------
1 | 'FORD'
1 | 'MUSTANG'
1 | '2010'
2 | 'FORD'
2 | 'FUSION'
2 | 'TURBO'
2 | '2010'
3 | 'FORD'
3 | 'RANGER'
3 | 'TURBO'
3 | '2010'
3 | 'BLACK'
Существует слишком FTS_TOKENIZE()
процедура для получения слов из целых строк
Случай 1: поиск пользователя по 1 ключевому слову
SELECT TOKENS FROM FTS_TOKENIZE('FORD')
TOKENS
-------------
'FORD'
Тогда это будет SQL, необходимый для получения правильных результатов:
:TOKEN_1 = 'FORD'
SELECT DISTINCT ID
FROM FTS_KEYWORDS
WHERE (KEYWORD STARTING :TOKEN_1)
ID
-----
1
2
3
Случай 2: поиск пользователя по 3 ключевым словам
SELECT TOKENS FROM FTS_TOKENIZE('FORD 2010 BLACK')
TOKENS
-------------
'FORD'
'2010'
'BLACK'
Итак, SQL для получения правильных значений:
:TOKEN_1 = 'FORD'
:TOKEN_2 = '2010'
:TOKEN_3 = 'BLACK'
SELECT DISTINCT K1.ID
FROM FTS_KEYWORDS K1
WHERE (K1.KEYWORD STARTING :TOKEN_1)
AND (K1.ID IN (SELECT DISTINCT K2.ID
FROM FTS_KEYWORDS K2
WHERE (K2.KEYWORD STARTING :TOKEN_2)))
AND (K2.ID IN (SELECT DISTINCT K3.ID
FROM FTS_KEYWORDS K3
WHERE (K3.KEYWORD STARTING :TOKEN_3)))
ID
-----
3
ID 3
является единственным ID
, в котором все ключевые слова соответствуют запросу.
SQL для получения значений является рекурсивным, вложенным поисковым запросом по количеству токенов.
В настоящее время в процедуре FTS_SEARCH()
я строю строку SQL и затем использую EXECUTE STATEMENT
, но я не думаю, что это идеально.
Я думаю, что это можно сделать с помощью рекурсивных выражений общих таблиц («WITH ... AS ... SELECT»), но я не смог этого сделать, поскольку, основываясь на текущих примерах доступно, требует таблицу с Parent_ID
и не принимает входные параметры, что не в моем случае.
У меня вопрос: есть ли способ сделать этот поиск рекурсивным способом, используя CTE или другой трюк SQL?