4

FTS 対応の SQLite データベースで奇妙な動作が見られます。fingerprintsという名前の列を含む という名前のテーブルがありますscan。scan のエントリは、次のような長い文字列です。

00:13:10:d5:69:88_-58;0c:85:25:68:b4:30_-75;0c:85:25:68:b4:34_-76;0c:85:25:68:b4:33_-76;0c:85:25:68:b4:31_-76;0c:85:25:68:b4:35_-76;00:23:eb:ad:f6:00_-87; etc

MAC アドレスと信号強度を表します。ここで、テーブルで文字列の照合を行い、たとえば MAC アドレスとの照合を試みます。

SELECT _id FROM fingerprints WHERE scan MATCH "00:13:10:d5:69:88";

これは、何らかの理由で指定された文字列を含まない多くの行を返します。2番目に一致させようとするのは

SELECT _id FROM fingerprints WHERE scan MATCH "00:13:10:d5:69:88_-58";

これは以前と同じ行を返し、完全に間違っています。

SQLite は: _ -文字を特別な方法で扱いますか?

ありがとう

4

1 に答える 1

4

表示されているのは、FTS がデータをトークン化した効果です。

全文検索は、未処理の長い文字列では機能しません。データ (および検索用語) を単語に分割し、個別にインデックスを作成します。デフォルトのトークナイザーは、すべての英数字とコード ポイントが 128 を超えるすべての文字を単語に使用し、残りの文字 (たとえば、ご覧のように: _ -) を単語の境界として使用します。

つまり、 を検索すると、単語andおよびandおよびandを任意の順序00:13:10:d5:69:88で含む行が検索されます。001310d56988

この動作を確認できます。

sqlite> CREATE VIRTUAL TABLE simple USING fts3(tokenize=simple);
sqlite> INSERT INTO simple VALUES('00:13:10:d5:69:88');
sqlite> SELECT * FROM simple WHERE simple MATCH '69:10';

-> 00:13:10:d5:69:88

編集: どうやら SQLite は、私が最初に信用したよりもスマートです。フレーズ クエリ (リンク先からページを下にスクロール)を使用して、問題を解決する単語シーケンスを探すことができます。フレーズ クエリは、スペース (または他の単語区切り文字) で区切られた一連の用語を二重引用符 (") で囲むことによって指定されます。

sqlite> SELECT * FROM simple WHERE simple MATCH '"69:10"';

-> No match

sqlite> SELECT * FROM simple WHERE simple MATCH '"69 88"';

-> 00:13:10:d5:69:88

sqlite> SELECT * FROM simple WHERE simple MATCH '"69:88"';

-> 00:13:10:d5:69:88
于 2013-02-19T04:14:45.270 に答える