Es fällt mir schwer zu verstehen, wie man die Volltextsuche (FTS) mit Android verwendet. Ich habe die SQLite-Dokumentation zu den Erweiterungen FTS3 und FTS4 gelesen . Und ich weiß, dass es auf Android möglich ist . Es fällt mir jedoch schwer, Beispiele zu finden, die ich verstehen kann.
Das grundlegende Datenbankmodell
Eine SQLite-Datenbanktabelle (benannt example_table
) enthält 4 Spalten. Es gibt jedoch nur eine Spalte (benannt text_column
), die für eine Volltextsuche indiziert werden muss. Jede Zeile text_column
enthält Text mit einer Länge von 0 bis 1000 Wörtern. Die Gesamtzahl der Zeilen ist größer als 10.000.
- Wie würden Sie die Tabelle und / oder die virtuelle FTS-Tabelle einrichten?
- Wie würden Sie eine FTS-Abfrage durchführen
text_column
?
Zusätzliche Bemerkungen:
- Da nur eine Spalte indiziert werden muss, wäre die Verwendung einer FTS-Tabelle (und das Löschen
example_table
) für Nicht-FTS-Abfragen ineffizient . - Für eine so große Tabelle wäre das Speichern doppelter Einträge
text_column
in der FTS-Tabelle unerwünscht. In diesem Beitrag wird die Verwendung einer externen Inhaltstabelle vorgeschlagen . - Externe Inhaltstabellen verwenden FTS4, aber FTS4 wird vor Android API 11 nicht unterstützt . Eine Antwort kann eine API> = 11 annehmen, aber das Kommentieren von Optionen zur Unterstützung niedrigerer Versionen wäre hilfreich.
- Durch Ändern der Daten in der Originaltabelle wird die FTS-Tabelle nicht automatisch aktualisiert (und umgekehrt). Das Einfügen von Triggern in Ihre Antwort ist für dieses grundlegende Beispiel nicht erforderlich, wäre aber dennoch hilfreich.
android
sqlite
full-text-search
Suragch
quelle
quelle
Antworten:
Grundlegendste Antwort
Ich benutze das einfache SQL unten, damit alles so klar und lesbar wie möglich ist. In Ihrem Projekt können Sie die Android-Convenience-Methoden verwenden. Das
db
unten verwendete Objekt ist eine Instanz von SQLiteDatabase .FTS-Tabelle erstellen
Dies könnte in die
onCreate()
Methode Ihrer erweitertenSQLiteOpenHelper
Klasse gehen.Füllen Sie die FTS-Tabelle aus
Es wäre besser, SQLiteDatabase # insert oder vorbereitete Anweisungen zu verwenden als
execSQL
.FTS-Tabelle abfragen
Sie können auch die SQLiteDatabase # -Abfragemethode verwenden. Beachten Sie das
MATCH
Schlüsselwort.Vollständigere Antwort
Die obige virtuelle FTS-Tabelle weist ein Problem auf. Jede Spalte ist indiziert, dies ist jedoch eine Verschwendung von Speicherplatz und Ressourcen, wenn einige Spalten nicht indiziert werden müssen. Die einzige Spalte, die einen FTS-Index benötigt, ist wahrscheinlich die
text_column
.Um dieses Problem zu lösen, verwenden wir eine Kombination aus einer regulären Tabelle und einer virtuellen FTS-Tabelle. Die FTS-Tabelle enthält den Index, jedoch keine der tatsächlichen Daten aus der regulären Tabelle. Stattdessen wird ein Link zum Inhalt der regulären Tabelle angezeigt. Dies wird als externe Inhaltstabelle bezeichnet .
Erstellen Sie die Tabellen
Beachten Sie, dass wir dafür FTS4 verwenden müssen, anstatt FTS3. FTS4 wird in Android vor API-Version 11 nicht unterstützt. Sie können entweder (1) nur Suchfunktionen für API> = 11 bereitstellen oder (2) eine FTS3-Tabelle verwenden (dies bedeutet jedoch, dass die Datenbank größer ist, da die Volltextspalte vorhanden ist in beiden Datenbanken).
Füllen Sie die Tabellen
(Auch hier gibt es bessere Möglichkeiten zum Einfügen von Beilagen als mit
execSQL
. Ich verwende es nur wegen seiner Lesbarkeit.)Wenn Sie jetzt versuchen würden, eine FTS-Abfrage durchzuführen
fts_example_table
, würden Sie keine Ergebnisse erhalten. Der Grund ist, dass das Ändern einer Tabelle die andere Tabelle nicht automatisch ändert. Sie müssen die FTS-Tabelle manuell aktualisieren:(Dies
docid
ist wierowid
bei einer regulären Tabelle.) Sie müssen sicherstellen, dass die FTS-Tabelle bei jeder Änderung (INSERT, DELETE, UPDATE) an der externen Inhaltstabelle aktualisiert wird (damit der Index aktualisiert werden kann). Dies kann umständlich werden. Wenn Sie nur eine vorab ausgefüllte Datenbank erstellen, können Sie dies tunDadurch wird die gesamte Tabelle neu erstellt. Dies kann jedoch langsam sein, sodass Sie es nicht nach jeder kleinen Änderung tun möchten. Sie würden dies tun, nachdem Sie alle Einfügungen in der externen Inhaltstabelle abgeschlossen haben. Wenn Sie die Datenbanken automatisch synchronisieren müssen, können Sie Trigger verwenden . Gehen Sie hierher und scrollen Sie ein wenig nach unten, um eine Wegbeschreibung zu finden.
Fragen Sie die Datenbanken ab
Dies ist das gleiche wie zuvor, außer dass Sie diesmal nur Zugriff auf
text_column
(unddocid
) haben. Was ist, wenn Sie Daten aus anderen Spalten in der externen Inhaltstabelle abrufen müssen? Da diedocid
der FTS-Tabelle mit derrowid
(und in diesem Fall_id
) der externen Inhaltstabelle übereinstimmt , können Sie einen Join verwenden. (Dank dieser Antwort für die Hilfe dabei.)Weiterführende Literatur
Sehen Sie sich diese Dokumente sorgfältig an, um weitere Möglichkeiten zur Verwendung virtueller FTS-Tabellen zu finden:
Zusätzliche Bemerkungen
UNION
oder Überprüfung erfordertPRAGMA compile_options
). Äußerst unglücklich. Bitte fügen Sie einen Kommentar hinzu, wenn es in diesem Bereich ein Update gibt.quelle
Vergessen Sie nicht, wenn Sie Inhalte von verwenden, um die fts-Tabelle neu zu erstellen.
Ich mache dies mit einem Auslöser beim Aktualisieren, Einfügen, Löschen
quelle
INSERT INTO foo_fts VALUES("rebuild")