2009-09-28 10 views
12

Powiedzmy masz jak następuje postgres'owy 8.3 tabela:Jak przeprowadzasz wyszukiwanie pełnotekstowe oparte na wyrażeniach w postgresie, które wykorzystuje indeks pełnotekstowy?

CREATE TABLE t1 (body text, body_vector tsvector);

Chcę być w stanie wyszukać go do zwrotów z wykorzystaniem pełnego indeksu tekstowego (GIST, gin albo oba na kolumnie tsvector). Najlepsze obejście, jakie udało mi się znaleźć, polega na tym, że najpierw należy przeszukać tekst na obu słowach (boolean AND), a następnie wykonać podobne porównanie na ciele dla frazy. Oczywiście nie udaje się to uchwycić żadnego sprawdzania pisowni lub sprawdzania pisowni, które wyszukuje pełnostronicowy postgres. Przykładem tego jest sytuacja, gdy szukam wyrażenie „w1 w2”, użyję:

SELECT * FROM t1 WHERE body_vector @@ 'w1 & w2'::tsquery AND body LIKE 'w1 w2';

Czy istnieje sposób, aby to zrobić, gdzie nie trzeba uciekać się do wyszukaniu kolumna tekstowa?

Odpowiedz

11

Jeśli chcesz dokładnie dopasować frazy, to jest sposób, aby to zrobić. Możesz także spróbować WHERE body_vector @@ plainto_tsquery ("w1 w2"), a następnie zamówić według rankingu. (Punkt jest, że trafienia gdzie słowa są tuż obok siebie, powinny zakończyć się na górze)

4

Aktualizacja: PostgreSQL 9.6 wyszukiwanie tekstu obsługuje fraz

select 
    * 
from (values 
    ('i heart new york'), 
    ('i hate york new') 
) docs(body) 
where 
    to_tsvector(body) @@ phraseto_tsquery('new york') 

(1 row retrieved) 

lub wg odległości między słowami:

-- a distance of exactly 2 "hops" between "quick" and "fox" 
select 
    * 
from (values 
    ('the quick brown fox'), 
    ('quick brown cute fox') 
) docs(body) 
where 
    to_tsvector(body) @@ to_tsquery('quick <2> fox') 

(1 row retrieved) 
+1

Może nie złapałem czegoś, ale czy nie wymaga to, aby ciąg wejściowy zawierał szukaną frazę między pojedynczymi cudzysłowami? Jak ktokolwiek mógłby go używać w ogóle, kiedy fraza pochodzi z wejścia auser, a dokument pochodzi z kolumny bazy danych? –

+1

To nadal nie jest "wyszukiwanie frazy". Działa to tylko dlatego, że twoje wyrażenie tsvector "new york" jest zawijane w pojedyncze cudzysłowy. – soyayix

+0

Tak, obie funkcje działają - ale twój ciąg tsvector w większości przypadków nie będzie zawierał cudzysłowów - jeśli tak, to jaka jest wyszukiwana fraza dla .. Mam postgreSQL 9.4 i zapytanie, które działa - to nie tylko specyficzne dla 9,6. wybierz "i serce new york city" :: tsvector @@ "nowy" :: tsquery, --true "i serce new york city" :: tsvector @@ "new & york" :: tsquery, - true 'i heart new york city' :: tsvector @@ '' new york '' ':: tsquery --false – soyayix

Powiązane problemy