Czy wszystkie zapytania muszą być w słowniku?
Nie. Ponieważ na początku w indeksie znajdują się tylko słowa kluczowe (zgodnie z używaną konfiguracją wyszukiwania tekstowego ). Ale co ważniejsze:
Nie . Ponieważ, na szczycie tej Full Text Search jest również zdolny do dopasowywania przedrostka :
To by działało:
SELECT id, subject
FROM mailboxes
WHERE tsv @@ to_tsquery('simple', 'avail:*')
ORDER BY id DESC;
Uwaga 3 rzeczy:
Użyj to_tsquery()
nie plainto_tsquery()
, w tym przypadku, ponieważ ( cytując instrukcję ):
... plainto_tsquery
nie rozpoznaje tsquery
operatorów, etykiet wagowych ani etykiet z dopasowaniem prefiksu w danych wejściowych
Użyj 'simple'
konfiguracji wyszukiwania tekstu, aby wygenerować, tsquery
ponieważ oczywiście chcesz wziąć słowo „skorzystaj”, jak jest, a nie stosować.
Dołącz, :*
aby uczynić to wyszukiwanie prefiksem, tzn. Znajdź wszystkie leksemy zaczynające się na „avail”.
Ważne: Jest to wyszukiwanie prefiksu leksemów (rdzeni słów) w dokumencie. Wyrażenie regularne bez symboli wieloznacznych ( content ~* 'avail'
) nie jest dokładnie takie samo! Ten ostatni nie jest zakotwiczony w lewo (do początku leksemów) i znalazłby również „FOOavail” itp.
Nie jest jasne, czy chcesz, aby zachowanie zostało przedstawione w zapytaniu, czy też odpowiednik dodanego wyrażenia regularnego. Sugerowane już indeksy Trigram ( pg_trgm
) jak @Evan są do tego odpowiednim narzędziem. Na dba.SE znajduje się wiele powiązanych pytań, spróbuj wyszukać .
Przegląd:
Próbny
SELECT *
FROM (
VALUES
('Zend has no framework')
, ('Zend Framework')
) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
id | t | tsv
----+----------------+------------------------
2 | Zend Framework | 'framework':2 'zend':1
Ostatnia pokrewna odpowiedź (rozdział Różne podejście do optymalizacji wyszukiwania ):
E-maile
Ponieważ wspomniałeś o wiadomościach e-mail, pamiętaj, że parser wyszukiwania tekstu identyfikuje wiadomości e-mail i nie dzieli ich na osobne słowa / leksemy. Rozważać:
SELECT ts_debug('english', '[email protected]')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})
Zastąpiłbym separatory @
i .
wiadomości e-mail spacją ( ' '
), aby indeksować zawarte słowa.
Ponadto, ponieważ masz do czynienia z nazwiskami w wiadomościach e-mail, a nie ze słowami angielskimi (lub innymi językami) , 'simple'
użyłbym konfiguracji wyszukiwania tekstowego, aby wyłączyć funkcję wyszukiwania i inne funkcje językowe :
Zbuduj ts_vector
kolumnę za pomocą:
SELECT to_tsvector('simple', translate('[email protected]', '@.', ' ')) AS tsv;
:*
udokumentowane, i 2) czy wzmianka o budowaniu nie powinnato_tsvector('simple'..)
iść w parze z instrukcjami, że przyszłe zapytania tego tsv będą wymagały również „prostej” konfiguracji do tsquery? Myślę, że powinieneś wyjaśnić konsekwencje wyłączenia w tsvector / tsquery.0.380ms
aby uzyskać wynik. Po twojej drodze to zajęło0.079 ms
.pg_trgm
. FTS jest szybszy (z mniejszym indeksem). Możesz nawet połączyć oba indeksy ...