1

Ich habe eine Postgres-Datenbank mit rund 1,5 Millionen Datensätzen. In meiner Ruby on Rails App muss ich das statement_text Feld durchsuchen (das irgendwo zwischen 1 und Hunderte von Wörtern enthalten kann).Was ist die beste Möglichkeit, nach einer genauen Übereinstimmung mit der Postgres-Volltextsuche zu suchen?

Mein Problem: Ich weiß, dass ich das pgSearch Juwel verwenden kann Bereiche wie search_all_words oder search_any_words zu schaffen, aber ich bin unsicher, was der effizienteste Weg ist nur Datensätze mit der genauen Übereinstimmung zu gewährleisten werden in der Ergebnismenge .

Das heißt, wenn ich "Papst Franziskus" suche, möchte ich, dass es nur diese zwei Wörter findet, wenn sie aufeinander folgen und in der gleichen Reihenfolge sind (im Gegensatz zu, sagen wir, "Der Papst heißt Franziskus").

Bisher habe ich nur einen GIN-Index mit ILIKE für die exakte Übereinstimmung Suchanfragen kombiniert. Aber da ein GIN-Index in jedem Datensatz im Wesentlichen nach storing the exact position of a word funktioniert, sollte es keinen effizienteren (nicht ILIKE) Weg geben, sicherzustellen, dass der Suchbegriff genau mit dem Feld übereinstimmt?

Antwort

1

Generell Volltext erfordert Wort auf Sprache Wörterbuch basiert sollen genutzt werden, so mit mit Volltextsuche Sie ts_rank() Funktion ohne stamm und mit 'simple'-Lexikon nutzen die Relevanz der Phrase zu bestimmen, für die Sie suchen .

WITH t(v) AS (VALUES 
    ('Test sentence with Pope Francis'), 
    ('Test Francis sentence with Pope '), 
    ('The pope is named Francis') 
) 
SELECT v,ts_rank(tsv,q) as rank 
FROM t, 
    to_tsvector('simple',v) as tsv, 
    plainto_tsquery('simple','Pope Francis') AS q; 

Ergebnis:

   v     | rank  
----------------------------------+----------- 
Test sentence with Pope Francis | 0.0991032 
Test Francis sentence with Pope | 0.0973585 
The pope is named Francis  | 0.0973585 
(3 rows) 

Ohne Volltextsuche können Sie einfach schneller implementieren ILIKE Muster mit pg_trgm Erweiterung entspricht. Beispiel ist here.

+0

Danke, Dmitry! Ich benutze die Volltextsuche, damit ich ts_rank verwenden kann. Das Problem ist jedoch, dass es - abhängig von der Wortanzahl des Feldes - keinen spezifischen Cutoff gibt, der sicherstellt, dass die Wörter benachbart und in der richtigen Reihenfolge sind, ohne ILIKE zu verwenden. Verstehe ich das richtig? – jayp

+0

nein, es gibt keinen abgeschnittenen basierend auf der Länge. Wenn es eine Übereinstimmung für die Phrase gibt, hat sie immer noch einen höheren Rang. Sie können den Normalisierungsfaktor für ts_rank weglassen - es sollte gut funktionieren. –

+0

OK, danke !! – jayp