Kann ich die Vereinigung des Postgres-Volltextindex erhalten?


7

Ich habe einen Volltextindex für eine Tabelle. Ist es möglich, die im Index ( gistoder gin) verwendeten Begriffe abzurufen ? Wenn möglich mit Gewichten?

Zu klären:

Wenn ich folgende Tabelle habe:

create table "test" (id integer, thing tsvector);

Ich mache dann einen GIST-Index darauf:

create index thing_index on test using gist (thing);

Dann einige Daten:

insert into test (id, thing)
values (1, 'one'),(2, 'two'), (3, 'three'), (4, 'one'), (5, 'two');

Der Index thing_indexenthält die folgende Zuordnung:

'one' => {1, 4}
'two' => {2, 5}
'three' => {3}

Ich möchte die folgende Antwort aus dem Index erhalten:

'one',
'two',
'three'

Vielleicht sogar mit Ranglisten:

'one' => 2
'two' => 2
'three' => 1

Ich weiß, dass ich dies selbst tun kann, indem ich meinen eigenen Index scanne und erstelle, aber ich möchte ihn nach Möglichkeit aus Postgres herausholen.


1
Was meinen Sie mit "im Index verwendeten Begriffen"? Ein Volltextindex indiziert alle Wörter in der Spalte.
Josh Berkus

1
Es könnte sich lohnen, Ihre Frage etwas näher zu erläutern, da ich vermute, dass niemand genau weiß, was Sie wollen, und es daher schwierig ist, sie zu beantworten.
Craig Ringer

Danke Josh und Craig, mir ist nicht in den Sinn gekommen, dass meine Frage unklar sein könnte. Ich habe ein funktionierendes Beispiel hinzugefügt.
Joe

Antworten:


1

Wenn ich Ihre Frage richtig verstehe und es überhaupt nicht klar ist, versuchen Sie, Informationen zurückzuziehen, soweit die IDs mit einem Wert verbunden sind. Ich glaube nicht, dass Sie es einfach aus dem Index in PostgreSQL ziehen können, da der Index keine Sichtbarkeitsinformationen enthält und Sie daher eine Menge zufälliger E / A haben und darauf warten, dass sich die Platten drehen.

Die Abfrage für Ihren Testfall lautet:

select thing, array_agg(id) from test group by thing;

Angenommen, Sie haben eine Version, die hoch genug ist, um array_agg zu haben.

In meinem System (9.1) gibt mir dies:

chris=> select thing, array_agg(id) from test group by thing;
   thing  | array_agg 
 ---------+-----------
  'one'   | {1,4}
  'two'   | {2,5}
  'three' | {3}
 (3 rows)

das ist was du suchst, oder?


Danke, das sieht hoffnungsvoll aus. Ich werde es versuchen. Ich bin auf 9.0 FWIW. Wie könnte ich die Frage stellen? Ich habe ein Beispiel für eine Eingabe und Ausgabe mit einer Erläuterung des Prozesses gegeben, mit dem ich möchte, dass einer in den anderen umgewandelt wird.
Joe

array_agg wurde eingeführt Ich denke in 8.4, also solltest du gut sein. Die Frage war nicht so klar, ob Sie nur diese Art der Aggregation wollten oder ob Sie herausfinden wollten, was ein Index für eine Tabelle halten sollte (was normalerweise eine Obermenge dessen ist, was er tatsächlich enthält).
Chris Travers

Ah OK. Nun, ich wollte den tatsächlichen Index, um einen vollständigen Tabellenscan zu vermeiden. Ich wollte nur den berechneten Zugriff auf den invertierten Index. Am Ende habe ich einen anderen Weg eingeschlagen (meinen eigenen berechnet), aber ich dachte, es lohnt sich, zuerst zu versuchen, ihn kostenlos zu bekommen.
Joe

1
Unter PostgreSQL vor 9.2 ist es nicht möglich, den Index zu erstellen und die Tabelle zu umgehen. Ab 9.2 können Sie vermutlich den Index staubsaugen und unter der Annahme, dass keine anderen Abfragen vorliegen, den Index verwenden (Deaktivieren von seq_scan). Bei Diskussionen über pgsql-general können sequentielle Scans der Tabelle jedoch tatsächlich schneller sein.
Chris Travers

1

Und was ist mit:

SELECT * FROM ts_stat('SELECT thing FROM test')                 
ORDER BY nentry DESC, ndoc DESC, word                              
LIMIT 100;

Funktioniert auf einen Blick für mich (S. 9.1) und zeigt eine Hitliste der in den Dokumenten verwendeten Wörter.

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.