Следуя этому ответу, я хочу знать, как лучше всего использовать встроенный полнотекстовый поиск PostgreSQL, если я хочу для сортировки по рангу и ограничиваются только совпадающими запросами.
Предположим, очень простая таблица.
CREATE TABLE pictures (
id SERIAL PRIMARY KEY,
title varchar(300),
...
)
или что-то еще. Теперь я хочу выполнить поиск в поле title
. Сначала создаю индекс:
CREATE INDEX pictures_title ON pictures
USING gin(to_tsvector('english', title));
Теперь я хочу найти 'small dog'
. Это работает:
SELECT pictures.id,
ts_rank_cd(
to_tsvector('english', pictures.title), 'small dog'
) AS score
FROM pictures
ORDER BY score DESC
Но на самом деле я хочу вот что:
SELECT pictures.id,
ts_rank_cd(
to_tsvector('english', pictures.title), to_tsquery('small dog')
) AS score
FROM pictures
WHERE to_tsvector('english', pictures.title) @@ to_tsquery('small dog')
ORDER BY score DESC
Или, альтернативно, это (что не работает - нельзя использовать score
в предложении WHERE
):
SELECT pictures.id,
ts_rank_cd(
to_tsvector('english', pictures.title), to_tsquery('small dog')
) AS score
FROM pictures WHERE score > 0
ORDER BY score DESC
Как лучше всего это сделать? У меня много вопросов:
- Если я использую версию с повторяющимся
to_tsvector(...)
, она вызовет это дважды или достаточно умен, чтобы каким-то образом кэшировать результаты? - Есть ли способ сделать это без повторения вызовов функций
to_ts...
? - Есть ли вообще способ использовать
score
в предложенииWHERE
? - Если есть, что лучше: отфильтровать по
score > 0
или использовать@@
?