Исходя из этого ответа, я хочу знать, как лучше всего использовать встроенный полнотекстовый поиск 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...
функцииto_ts...
? - Есть ли способ использовать
score
вWHERE
? - Если есть, было бы лучше отфильтровать по
score > 0
или использовать@@
вещь?