Najbardziej podstawowa Answer
używam zwykłego sql poniżej tak, że wszystko jest jasne i czytelne, jak to możliwe. W swoim projekcie możesz skorzystać z wygodnych metod Android. Zastosowany poniżej obiekt db
jest instancją SQLiteDatabase.
Create FTS Table
db.execSQL("CREATE VIRTUAL TABLE fts_table USING fts3 (col_1, col_2, text_column)");
To może iść w sposobie swojego rozszerzonego SQLiteOpenHelper
klasy onCreate()
.
Populate FTS Table
db.execSQL("INSERT INTO fts_table VALUES ('3', 'apple', 'Hello. How are you?')");
db.execSQL("INSERT INTO fts_table VALUES ('24', 'car', 'Fine. Thank you.')");
db.execSQL("INSERT INTO fts_table VALUES ('13', 'book', 'This is an example.')");
Byłoby lepiej używać SQLiteDatabase#insert lub prepared statements niż execSQL
.
Query FTS Table
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_table WHERE fts_table MATCH ?", selectionArgs);
Można również użyć metody SQLiteDatabase#query. Zwróć uwagę na słowo kluczowe MATCH
.
Fuller Odpowiedź
powyżej wirtualny stół FTS ma z tym problem. Każda kolumna jest indeksowana, ale jest to strata miejsca i zasobów, jeśli niektóre kolumny nie muszą być indeksowane. Jedyną kolumną, która potrzebuje indeksu FTS, jest prawdopodobnie text_column
.
Aby rozwiązać ten problem, użyjemy kombinacji zwykłego stołu i wirtualnej tabeli FTS. Tabela FTS będzie zawierała indeks, ale żadne rzeczywiste dane z normalnej tabeli. Zamiast tego będzie zawierał link do zawartości zwykłej tabeli. Nazywa się to external content table.
utworzyć tabele
db.execSQL("CREATE TABLE example_table (_id INTEGER PRIMARY KEY, col_1 INTEGER, col_2 TEXT, text_column TEXT)");
db.execSQL("CREATE VIRTUAL TABLE fts_example_table USING fts4 (content='example_table', text_column)");
Zauważ, że mamy do wykorzystania FTS4 to zrobić zamiast FTS3. FTS4 nie jest obsługiwany w systemie Android przed wersją interfejsu API 11. Możesz (1) zapewnić tylko funkcję wyszukiwania dla API> = 11 lub (2) użyć tabeli FTS3 (ale oznacza to, że baza danych będzie większa, ponieważ kolumna pełnego tekstu istnieje w obu bazach danych).
wypełnić tabele
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('3', 'apple', 'Hello. How are you?')");
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('24', 'car', 'Fine. Thank you.')");
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('13', 'book', 'This is an example.')");
(Ponownie, istnieją lepsze sposoby na temat wkładki niż execSQL
. Ja po prostu używając go do jego czytelności.)
Jeśli próbowali zrobić Zapytanie FTS teraz na fts_example_table
nie dostaniesz żadnych wyników. Powodem jest to, że zmiana jednej tabeli nie powoduje automatycznej zmiany drugiej tabeli. Trzeba ręcznie zaktualizować tabelę FTS:
db.execSQL("INSERT INTO fts_example_table (docid, text_column) SELECT _id, text_column FROM example_table");
(. Na docid
jest jak rowid
do regularnego tabeli) trzeba się upewnić, aby zaktualizować tabelę FTS (tak, że można go zaktualizować indeks) za każdym razem, wprowadzasz zmianę (INSERT, DELETE, UPDATE) do zewnętrznej tabeli treści. Może to być uciążliwe. Jeśli tworzysz tylko wstępnie wypełnioną bazę danych, możesz wykonać , która odbuduje całą tabelę. Może to być powolne, więc nie jest to coś, co chcesz zrobić po każdej małej zmianie. Zrobiłbyś to po skończeniu wszystkich wstawień w zewnętrznej tabeli treści. Jeśli zachodzi potrzeba automatycznego synchronizowania baz danych, można użyć numeru triggers. Go here i przewiń w dół, aby znaleźć wskazówki.
kwerendy baz danych
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_example_table WHERE fts_example_table MATCH ?", selectionArgs);
To jest taki sam jak poprzednio, ale tym razem masz tylko dostęp do text_column
(i docid
). Co się stanie, jeśli chcesz pobrać dane z innych kolumn z zewnętrznej tabeli treści? Ponieważ docid
tabeli FTS pasuje do rowid
(iw tym przypadku _id
) tabeli zawartości zewnętrznej, można użyć łączenia. (Podziękowania dla this answer za pomoc.)
String sql = "SELECT * FROM example_table WHERE _id IN " +
"(SELECT docid FROM fts_example_table WHERE fts_example_table MATCH ?)";
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery(sql, selectionArgs);
Dalsze Reading
przejść przez te dokumenty starannie aby zobaczyć inne sposoby wykorzystania FTS wirtualne tabele:
Uwagi dodatkowe
dobrze udokumentowane pytanie, jestem przeciwdziałaniu arbitralną downvote tu dostałeś. – Mekap