2012-10-17 8 views
10

opierając się na this answer Chcę wiedzieć, jaki jest najlepszy sposób na wykorzystanie PostgreSQL wbudowanego wyszukiwania pełnotekstowego jest, jeśli chcę sortować według rangi, i limitu tylko dopasowanych zapytań .Najlepszy sposób na wykorzystanie PostgreSQL przeszukiwanie pełnego tekstu Ranking

Załóżmy bardzo prosty stół.

CREATE TABLE pictures { 
    id SERIAL PRIMARY KEY, 
    title varchar(300), 
    ... 
} 

lub coś innego. Teraz chcę przeszukać pole title. Najpierw tworzę indeks:

CREATE INDEX pictures_title ON pictures USING gin(to_tsvector('english', title)); 

Teraz chcę wyszukać 'small dog'. To działa:

SELECT pictures.id, ts_rank_cd(to_tsvector('english', pictures.title), 'small dog') AS score 
FROM pictures 
ORDER BY score DESC 

Ale to, co naprawdę chcę to:

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 

Lub alternatywnie ten (który nie działa - nie można używać score w klauzuli 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 

Jaki jest najlepszy sposób na zrobienie tego? Moje pytania to wiele razy:

  1. Jeśli używam wersji z wielokrotnym to_tsvector(...) to nazwać, że dwa razy, czy jest wystarczająco inteligentny, aby buforować wyniki jakoś?
  2. Czy istnieje sposób, aby to zrobić bez powtarzania wywołań funkcji to_ts...?
  3. Czy istnieje sposób użycia score w klauzuli WHERE w ogóle?
  4. Jeśli tak, to czy lepiej jest filtrować przez score > 0 lub użyć funkcji @@?

Odpowiedz

10
select * 
from (
    SELECT 
     pictures.id, 
     ts_rank_cd(to_tsvector('english', pictures.title), 
     to_tsquery('small dog')) AS score 
    FROM pictures 
) s 
WHERE score > 0 
ORDER BY score DESC 
5

Jeśli używam wersji z wielokrotnym to_tsvector (...) będzie to nazwać, że dwa razy, czy jest wystarczająco inteligentny, aby buforować wyniki jakoś?

Najlepszym sposobem na zauważenie tych rzeczy jest proste wyjaśnienie, chociaż trudno je odczytać.

Krótko mówiąc, tak, PostgreSQL jest wystarczająco inteligentny, aby ponownie wykorzystać wyniki obliczeń.

Czy istnieje sposób, aby to zrobić bez powtarzania funkcji to_ts ... wywołań funkcji?

Zazwyczaj dodaję kolumnę tsv, która jest tekstem wyszukiwania. Jeśli wykonasz tę automatyczną aktualizację za pomocą wyzwalaczy, natychmiast udostępnisz wektor łatwo dostępny, ale także umożliwi selektywną aktualizację indeksu wyszukiwania przez wybranie selektywnego wyzwalacza.

Czy istnieje sposób na zastosowanie wyniku w klauzuli WHERE w ogóle?

Tak, ale nie z tym imieniem. Alternatywnie można utworzyć pod-zapytanie, ale ja osobiście po prostu powtórzę.

Jeśli tak, to czy lepiej filtrować według wyniku> 0 lub użyć rzeczy @@?

Najprostsza wersja mogę myśleć to:

SELECT * 
FROM pictures 
WHERE 'small dog' @@ text_search_vector 

text_search_vector mógłby oczywiście być zastąpione czymś jak to_tsvector('english', pictures.title)

+0

Ta odpowiedź ignoruje co seemse być najważniejsza część pytania: "zaszeregowanie" – steviejay