Seite 1 von 1

Wie kann man nach dem Upsize eine Volltextsuche hinzufügen? [ERLEDIGT]

Verfasst: Mi, 24. Feb 2021 16:33
von dtmackenzie
Hallo alle,

beim Upsize auf Postgres kann man eine Volltextsuche hinzufügen, tolle Sache, geht richtig schnell.

Ich finde aber leider keine Informationen darüber, wie man dies im Normalbetrieb (nach dem Upsize) macht.
Steht bestimmt irgendwo beschrieben, aber weißt jemand zufällig wo?

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Di, 09. Mär 2021 16:42
von dtmackenzie
Gibt es eine Möglichkeit, die gleiche Funktion aufzurufen, die das Upsize benutzt?

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Di, 09. Mär 2021 21:26
von HaPe
Normalerweise kann man bei SQL-Servern die Volltext-Suche nur bei der Erstellung der Datenbank angeben (gerade wieder in einem Vortrag gehört - nicht zu PostGreSQL).

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Mi, 10. Mär 2021 9:34
von dtmackenzie
Hallo HaPe,

Danke für Deine Antwort!

Inzwischen habe ich für den konkreten Fall die Datenbank "neugeupsized", habe aber nun auch in der Hilfe zumindest eine allgemeine Beschreibung des Vorgangs gefunden unter:
Xbase++ Developer Bookshelf / Database Engines / PostgreSQL... / Samples... / Upsizing MDIDEMO / Adding full-text search / Behind the scenes
Da drin steht u.a. Folgendes:
The deferred action creating a full-text search index does a number of things on behalf of the SQL server:
* Alters the table to add a field "fts_col" with the "tsvector" data type.
* Executes an UPDATE statement for storing the transformed textual data from the fields listed in the binding clause into "fts_col".
* Creates a GIST index for the "fts_col" field.
* Creates a trigger to automatically maintain the "fts_col" data if changes occur in one of the bound fields (lastname, firstname, city, notes).
Die Prozedur sollte manuell nachvollziehbar sein wenn ich eine schon konvertierte Tabelle anschaue (ich nehme an, dass das UPDATE Ähnliches machen soll wie im Trigger zu sehen ist), vielleicht lässt sie sich doch in eine Funktion kapseln, das versuche ich nächstes Mal.

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Mi, 10. Mär 2021 11:00
von nightcrawler
HaPe hat geschrieben: Di, 09. Mär 2021 21:26 Normalerweise kann man bei SQL-Servern die Volltext-Suche nur bei der Erstellung der Datenbank angeben
gilt nicht für alle. Ich kenne mindestens einen, bei dem eine Volltextsuche auch nachträglich per Index angelegt werden kann;)

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Mi, 10. Mär 2021 11:04
von Tom
Die Schritte, die David aus der Doku zitiert hat, ließen sich natürlich auch nachträglich anwenden - wenn man genauere Kenntnis über sie hätte.

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Mi, 10. Mär 2021 11:19
von dtmackenzie
Danke nightcrawler und Tom,

ich glaube, das Meiste müsste in der Postgres-Doku zu finden sein.

Mit pgAdmin4 sehe ich die Trigger, die vom Upsize angelegt wurden, z.B:

Code: Alles auswählen

begin
  new.fts_col_ang := to_tsvector(coalesce(new.bemerk,''))||to_tsvector(coalesce(new.benutzer,''))||to_tsvector(coalesce(new.ktb,''))||to_tsvector(coalesce(new.ftb,''))||to_tsvector(coalesce(new.info,''));
return new;
end
Ich vermute, dass das UPDATE genau das Gleiche machen müsste, nur für die ganze Tabelle anstatt eines einzelnen Datensatzes.

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Do, 11. Mär 2021 9:41
von nightcrawler
Hallo David,
es gibt einen Trick, wie man jeden Datensatz anfassen kann und somit die Update-Trigger der einzelnen Datensätze feuert:

Code: Alles auswählen

UPDATE [tabelle] SET [einfeld]=[einfeld]

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Do, 11. Mär 2021 9:47
von dtmackenzie
Hallo Joachim,

das gefällt mir sehr, vermeidet Code-Duplizierung, Danke!

Wie gesagt, ich habe im aktuellen Fall ein erneutes Upsize gemacht, aber nächstes Mal habe ich vor, doch ein Programmchen dafür zu schreiben und hier zu posten.

Re: Wie kann man nach dem Upsize eine Volltextsuche hinzufügen?

Verfasst: Do, 25. Mär 2021 14:08
von dtmackenzie
Es ist soweit, musste ich doch noch eine Volltextsuche hinzufügen!
Keine Garantien, aber folgender Code ging für mich, ist hoffentlich selbsterklärend...

Code: Alles auswählen

FUNC XSQL(cSQL)
LOCAL oStmt:=DacSqlStatement():fromChar(cSQL)
RETURN oStmt:build():execute()


PROC AddFullTextSearch(cTableName, aFieldNames)
LOCAL cFTS_Col:="fts_col_"+cTableName, cFieldNames:="", cFirstField:=aFieldNames[1],;
      cSQL:="", cTFName:=cFTS_Col+"_tsvector_trigger()", cr:=CHR(13)

// Procedure based (slightly modified) upon Xbase++ help:
// Xbase++ Developer Bookshelf / Database Engines / PostgreSQL... / Samples...
//            / Upsizing MDIDEMO / Adding full-text search / Behind the scenes
// Most comments are "borrowed" from there.

// Assumes that the current DacSession is connected and has sufficient privileges.
// No error-handling!


// Alter the table to add a field <cFTS_Col> with the "tsvector" data type.
cSQL := "ALTER TABLE " + cTableName + " ADD COLUMN " + cFTS_Col + " tsvector"
XSQL(cSQL)


// Create a GIST index for the <cFTS_Col> field.
AEVAL(aFieldNames, {|c| cFieldNames += c + " "})
cSQL := "CREATE INDEX " + cFTS_Col + "_idx ON " + cTableName +;
        " USING gist ( " + cFTS_Col + ")"
XSQL(cSQL)


// Create a trigger to automatically maintain the <cFTS_Col> data
// if changes occur in one of the bound fields.

cSQL := "CREATE FUNCTION public." + cTFName + cr
cSQL += "    RETURNS trigger" + cr
cSQL += "    LANGUAGE 'plpgsql'" + cr
cSQL += "    COST 100" + cr
cSQL += "    VOLATILE NOT LEAKPROOF" + cr
cSQL += "AS $BODY$" + cr
cSQL += "begin" + cr
cSQL += "  new." + cFTS_Col + " := " + cr
cSQL +=   "to_tsvector(coalesce(new." + cFirstField + ",''))"
AEVAL(aFieldNames, {|c| cSQL += "||to_tsvector(coalesce(new." + c + ",''))"}, 2)
cSQL +=   ";" + cr
cSQL += "return new;" + cr
cSQL += "end" + cr
cSQL += "$BODY$;" + cr
XSQL(cSQL)

cSQL := "CREATE TRIGGER " + cFTS_Col + "_tsvector_update" + cr
cSQL += "    BEFORE INSERT OR UPDATE" + cr
cSQL += "    ON public." + cTableName + cr
cSQL += "    FOR EACH ROW" + cr
cSQL += "    EXECUTE PROCEDURE public." + cTFName + cr
XSQL(cSQL)


// Execute an UPDATE statement for storing the transformed textual data
// from the fields listed in the binding clause into <cFTS_Col>.
// Thanks to nightcrawler in Xbase forum for the elegant solution!

cSQL := "UPDATE " + cTableName + " SET " + cFirstField + "=" + cFirstField
XSQL(cSQL)

RETURN