最も基本的な答え
私は以下のプレーンSQLを使用して、すべてが可能な限り明確で読みやすいようにしています。プロジェクトでは、Androidの便利なメソッドを使用できます。db
以下に使用されるオブジェクトは、インスタンスであるSQLiteDatabase。
FTSテーブルを作成する
db.execSQL("CREATE VIRTUAL TABLE fts_table USING fts3 ( col_1, col_2, text_column )");
これonCreate()
は、拡張SQLiteOpenHelper
クラスのメソッドに含まれる可能性があります。
FTSテーブルにデータを入力します
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.')");
それは使用する方が良いでしょうSQLiteDatabase#挿入またはプリペアドステートメントよりをexecSQL
。
FTSテーブルのクエリ
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_table WHERE fts_table MATCH ?", selectionArgs);
SQLiteDatabase#queryメソッドを使用することもできます。MATCH
キーワードに注意してください。
より完全な答え
上記の仮想FTSテーブルには問題があります。すべての列にインデックスが付けられますが、一部の列にインデックスを付ける必要がない場合、これはスペースとリソースの浪費です。FTSインデックスを必要とする唯一の列は、おそらくtext_column
。です。
この問題を解決するために、通常のテーブルと仮想FTSテーブルの組み合わせを使用します。FTSテーブルにはインデックスが含まれますが、通常のテーブルの実際のデータは含まれません。代わりに、通常のテーブルのコンテンツへのリンクがあります。これは外部コンテンツテーブルと呼ばれます。
テーブルを作成する
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)");
これを行うには、FTS3ではなくFTS4を使用する必要があることに注意してください。FTS4は、APIバージョン11より前のAndroidではサポートされていません。(1)API> = 11の検索機能のみを提供するか、(2)FTS3テーブルを使用することができます(ただし、全文列が存在するため、データベースが大きくなります)両方のデータベースで)。
テーブルにデータを入力します
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.')");
(繰り返しになりますが、挿入を行うには、挿入を行うよりも優れた方法がありますexecSQL
。読みやすさのために使用しています。)
今すぐFTSクエリを実行しようとすると、fts_example_table
結果が得られません。その理由は、一方のテーブルを変更しても、もう一方のテーブルは自動的に変更されないためです。FTSテーブルを手動で更新する必要があります。
db.execSQL("INSERT INTO fts_example_table (docid, text_column) SELECT _id, text_column FROM example_table");
(これdocid
はrowid
通常のテーブルの場合と同様です。)外部コンテンツテーブルに変更(INSERT、DELETE、UPDATE)を行うたびに、必ずFTSテーブルを更新する必要があります(インデックスを更新できるようにするため)。これは面倒になる可能性があります。事前入力されたデータベースのみを作成している場合は、次のことができます。
db.execSQL("INSERT INTO fts_example_table(fts_example_table) VALUES('rebuild')");
これにより、テーブル全体が再構築されます。ただし、これは遅くなる可能性があるため、少し変更するたびに実行したいことではありません。外部コンテンツテーブルへのすべての挿入が完了した後で実行します。データベースの同期を自動的に維持する必要がある場合は、トリガーを使用できます。ここに行き、少し下にスクロールして道順を見つけます。
データベースのクエリ
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_example_table WHERE fts_example_table MATCH ?", selectionArgs);
これは以前と同じですが、今回はtext_column
(とdocid
)にしかアクセスできない点が異なります。外部コンテンツテーブルの他の列からデータを取得する必要がある場合はどうなりますか?以来docid
FTSテーブルの一致したrowid
(この場合には_id
、外部コンテンツテーブルの)を、あなたが参加することができます。(それを助けてくれたこの答えに感謝します。)
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);
参考文献
これらのドキュメントを注意深く調べて、FTS仮想テーブルを使用する他の方法を確認してください。
その他の注意事項