Ermittelt eine teilweise Übereinstimmung aus der GIN-indizierten TSVECTOR-Spalte


13

Ich möchte folgende Ergebnisse per Abfrage erhalten:

SELECT * FROM (
  SELECT id, subject
  FROM mailboxes
  WHERE tsv @@ plainto_tsquery('avail')
) AS t1 ORDER by id DESC;

Dies funktioniert und gibt Zeilen mit tsvcontain zurück Available. Aber wenn ich es benutze avai(fallen lasse lable), kann es nichts finden.

Müssen alle Abfragen im Wörterbuch sein? Können wir solche Briefe nicht einfach abfragen? Ich habe eine Datenbank, die E-Mail-Text (Inhalt) enthält, und ich möchte sie so schnell wie möglich erweitern. Zur Zeit benutze ich

... WHERE content ~* 'letters`

Antworten:


22

Müssen alle Abfragen im Wörterbuch sein?

Nein, da sich im Index zunächst nur Wortstämme (entsprechend der verwendeten Textsuchkonfiguration ) befinden. Aber noch wichtiger:

Nein . Darüber hinaus kann die Volltextsuche auch mit folgenden Präfixen verglichen werden :

Das würde funktionieren:

SELECT id, subject
FROM   mailboxes
WHERE  tsv @@ to_tsquery('simple', 'avail:*')
ORDER  BY id DESC;

Beachten Sie 3 Dinge:

  1. Verwenden Sie in diesem Fall to_tsquery()nicht plainto_tsquery(), weil (unter Bezugnahme auf das Handbuch ):

    ... plainto_tsqueryerkennt tsqueryin der Eingabe keine Operatoren, Gewichtungsbezeichnungen oder Präfix-Übereinstimmungsbezeichnungen

  2. Verwenden Sie die 'simple'Konfiguration für die Textsuche, um das zu generieren, tsqueryda Sie offensichtlich das Wort 'avail' so wie es ist und kein Stemming anwenden möchten .

  3. Hänge :*an, um eine Präfixsuche zu machen, dh finde alle Lexeme, die mit 'avail' beginnen.

Wichtig: Dies ist eine Präfixsuche nach Lexemen (Wortstämmen) im Dokument. Eine Übereinstimmung mit regulären Ausdrücken ohne Platzhalter ( content ~* 'avail') ist nicht genau dasselbe! Letzterer ist nicht verankert (bis zum Beginn der Lexeme) und würde auch "FOOavail" usw. finden.

Es ist unklar, ob Sie das in Ihrer Abfrage beschriebene Verhalten oder das Äquivalent des hinzugefügten regulären Ausdrucks wünschen. Trigramm-Indizes ( pg_trgm) wie @Evan sind dafür das richtige Werkzeug. Es gibt viele verwandte Fragen zu dba.SE, versuchen Sie eine Suche .

Überblick:

Demo

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

Letzte verwandte Antwort (Kapitel Unterschiedlicher Ansatz zur Optimierung der Suche ):

E-Mails?

Da Sie E-Mails erwähnt haben, beachten Sie, dass der Parser für die Textsuche E-Mails identifiziert und diese nicht in separate Wörter / Lexeme aufteilt. Erwägen:

SELECT ts_debug('english', 'xangr@some.domain.com')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})

Ich würde die Trennzeichen @und .in Ihren E-Mails durch Leerzeichen ( ' ') ersetzen, um die enthaltenen Wörter zu indizieren.

Auch, weil Sie es zu tun Namen in E - Mails, nicht mit Englisch (oder eine andere Sprache) Wörter , würde ich die Verwendung 'simple'Textsuche Konfiguration zu deaktivieren entwickelt wurden und andere Sprache Funktionen:

Erstellen Sie die ts_vectorSpalte mit:

SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', '  ')) AS tsv;

Ich lösche meine Antwort auf diese Frage, weil ich mich zum ersten Mal eindeutig geirrt habe und nicht daran erinnert werden möchte. Ich habe zwei Fragen an Sie: 1) Wo ist dies :*dokumentiert to_tsvector('simple'..)? 2) Sollte eine Erwähnung zum Erstellen nicht mit Anweisungen einhergehen, die bei zukünftigen Abfragen dieses TSV auch die 'einfache' Konfiguration erfordern, um dies abzufragen? Ich denke, Sie sollten die Konsequenzen der Deaktivierung des Stemmings auf einem tsvector / tsquery klären.
Evan Carroll

@EvanCarroll: Die Verwendung der 'einfachen' Konfiguration ist nicht erforderlich . Es wird nur vermieden, dass Stämme (wie "Ratten" zu "Ratten") entstehen, die wünschenswert sein können oder auch nicht. Für das gegebene Beispiel nicht wünschenswert. Handbuch: Ich habe oben Links hinzugefügt ...
Erwin Brandstetter

4
@EvanCarroll: Nebenbei: Zu denken, dass du das erste Mal falsch liegst , wäre das zweite Mal. Und das wäre rekursiv falsch. ;)
Erwin Brandstetter

2
@ErwinBrandstetter, Wow, dein Weg hat mir gerade die volle Suchgeschwindigkeit gegeben. Vor deinem Weg brauchte es 0.380ms, um ein Ergebnis zu erzielen . Nach deinem Weg hat es gedauert 0.079 ms.
Xangr

1
@xangr: Nein, FTS bietet nur Präfix- Übereinstimmungen für Lexeme an. Für mehr schauen Sie zu pg_trgm. FTS ist schneller (mit kleinerem Index). Sie können sogar beide Indizes kombinieren ...
Erwin Brandstetter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.