やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SQLite3拡張 ICUで全文検索する(FTS4)

 条件が厳しいわりに微妙。

成果物

前提

 SQLite3を用意する。

 ICUを有効にする。動的ロードだけだとエラーになる。

 SQLite3.29.0はデフォルトでFTS4が有効なのでそこは気にしなくてOK。

SQLite3を実行する

 ターミナルで以下コマンドを実行する。

sqlite3

テスト用テーブル作成

begin transaction;
create virtual table posts using fts4(id, title, body, tokenize=icu ja_JP);
insert into posts values(1, '最初のタイトルです', '最初の本文です。');
insert into posts values(2, '二番目のタイトルです', '二番目の本文です。');
commit;

 もしコンパイルオプションにENABLE_ICUがなければ以下エラーになる。コンパイルオプションはpragma compile_options;で確認できる。ICU拡張を動的ロードするだけではダメ。

Error: unknown tokenizer: icu

全文検索する

select * from posts where posts match '最初';
1|最初のタイトルです|最初の本文です。
select * from posts where posts match 'タイトル';
1|最初のタイトルです|最初の本文です。
2|二番目のタイトルです|二番目の本文です。
select * from posts where posts match 'title:タイトル';
1|最初のタイトルです|最初の本文です。
2|二番目のタイトルです|二番目の本文です。
select * from posts where posts match 'title:タイト*';
1|最初のタイトルです|最初の本文です。
2|二番目のタイトルです|二番目の本文です。
select * from posts where posts match 'body:タイトル';





select * from posts where posts match '最初 タイトル';
1|最初のタイトルです|最初の本文です。

 以下は何もヒットしなかった。FTS4は省略形が使えないらしい。

select * from posts('タイトル');
select * from posts('title:タイトル');

 以下もヒットしない。なぜ?

select * from posts where posts match 'title:タイトル AND body:本文';
select * from posts where posts match '最初 AND タイトル';
select * from posts where posts match '最初' AND 'タイトル';
select * from posts where posts match 'NOT 最初';

 以下は間違っている。

select * from posts where posts match '最初 OR 二番目';
2|二番目のタイトルです|二番目の本文です。

 論理演算がおかしい……。

 あと、FTS4はorder by rankが使えない。

ICUはFTS5で使えない

create virtual table posts using fts5(id, title, body, tokenize=icu ja_JP);
Error: parse error in "tokenize=icu ja_JP"
create virtual table posts using fts5(id, title, body, tokenize='icu ja_JP');
Error: no such tokenizer: icu
create virtual table posts using fts5(id, title, body, tokenize="icu ja_JP");
Error: no such tokenizer: icu

 公式サイトにもそう書いてある。

The ICU tokenizer is not available.

所感

 ICUトークナイザとして使うならFTS4FTS5は使えない。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

前回まで