En Temel Cevap
Her şeyin olabildiğince açık ve okunaklı olması için aşağıdaki düz sql kullanıyorum. Projenizde Android kolaylık yöntemlerini kullanabilirsiniz. db
Aşağıda kullanılan nesne bir örneğidir SQLiteDatabase .
FTS Tablosu Oluştur
db.execSQL("CREATE VIRTUAL TABLE fts_table USING fts3 ( col_1, col_2, text_column )");
Bu onCreate()
, genişletilmiş SQLiteOpenHelper
sınıfınızın yöntemine girebilir .
FTS Tablosunu Doldur
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.')");
Kullanımı daha iyi olurdu SQLiteDatabase # insert veya hazır deyimleri daha execSQL
.
Sorgu FTS Tablosu
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_table WHERE fts_table MATCH ?", selectionArgs);
Ayrıca SQLiteDatabase # sorgu yöntemini de kullanabilirsiniz . Not MATCH
anahtar kelime.
Fuller Cevap
Yukarıdaki sanal FTS tablosunda bununla ilgili bir sorun var. Her sütun dizine eklenir, ancak bazı sütunların dizine eklenmesi gerekmiyorsa bu alan ve kaynak israfıdır. FTS indeksine ihtiyaç duyan tek sütun muhtemelen text_column
.
Bu sorunu çözmek için normal bir tablo ile sanal bir FTS tablosunun bir kombinasyonunu kullanacağız. FTS tablosu dizini içerecek, ancak normal tablodaki gerçek verilerin hiçbirini içermeyecektir. Bunun yerine, normal tablonun içeriğine bir bağlantı olacaktır. Buna harici içerik tablosu denir .
Tabloları Oluşturun
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)");
Bunu yapmak için FTS3 yerine FTS4 kullanmamız gerektiğine dikkat edin. FTS4, API sürüm 11'den önce Android'de desteklenmez. (1) yalnızca API> = 11 için arama işlevi sağlayabilir veya (2) bir FTS3 tablosu kullanabilirsiniz (ancak bu, tam metin sütunu olduğundan veri tabanının daha büyük olacağı anlamına gelir her iki veritabanında).
Tabloları Doldurun
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.')");
(Yine, uçlarda yapmaktan daha iyi yollar var execSQL
. Okunabilirliği için kullanıyorum.)
Şimdi bir FTS sorgusu yapmaya çalıştıysanız, fts_example_table
sonuç alamazsınız. Bunun nedeni, bir tabloyu değiştirmenin diğer tabloyu otomatik olarak değiştirmemesidir. FTS tablosunu manuel olarak güncellemeniz gerekir:
db.execSQL("INSERT INTO fts_example_table (docid, text_column) SELECT _id, text_column FROM example_table");
(Bu docid
, rowid
normal bir tablo gibidir.) Harici içerik tablosunda her değişiklik yaptığınızda (INSERT, DELETE, UPDATE) FTS tablosunu (dizini güncelleyebilmesi için) güncellediğinizden emin olmalısınız. Bu külfetli olabilir. Yalnızca önceden doldurulmuş bir veritabanı oluşturuyorsanız, şunları yapabilirsiniz:
db.execSQL("INSERT INTO fts_example_table(fts_example_table) VALUES('rebuild')");
tüm tabloyu yeniden inşa edecek. Bu yavaş olabilir, bu yüzden her küçük değişiklikten sonra yapmak isteyeceğiniz bir şey değildir. Harici içerik tablosundaki tüm ekleri tamamladıktan sonra yaparsınız. Veritabanlarını otomatik olarak senkronize tutmanız gerekiyorsa, tetikleyicileri kullanabilirsiniz . Yön bulmak için buraya gidin ve biraz aşağı kaydırın.
Veritabanlarını Sorgula
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_example_table WHERE fts_example_table MATCH ?", selectionArgs);
Bu, öncekiyle aynıdır, ancak bu sefer yalnızca text_column
(ve docid
) öğelerine erişiminiz vardır . Harici içerik tablosundaki diğer sütunlardan veri almanız gerekirse ne olur? Yana docid
FTS tablonun maçları rowid
(ve bu durumda _id
dış İçerik tablosunun), bir katılmak kullanabilirsiniz. ( Bununla ilgili yardım için bu cevap sayesinde .)
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);
Daha fazla okuma
FTS sanal tablolarını kullanmanın diğer yollarını görmek için bu belgeleri dikkatlice gözden geçirin:
ek Notlar