如何启用FTS5搜索带有“。”,“_”和“0-9”的字符串?

时间:2017-08-14 19:24:13

标签: python-3.x sqlite full-text-search fts5

我有一个表,使用字母数字,数字,点,下划线和括号[]来保存300K字符串记录。

我对sqlite3使用FTS5扩展来启用对该表的快速搜索。 这就是我创建FTS虚拟表的方法:

database = sqlite3.connect("mydb.db")
db_cursor = database.cursor()
db_cursor.execute("create virtual table field_names USING fts5 (full_path)")

我在循环中使用以下代码添加~300K记录:

database.execute("insert into field_names(full_path) values (?)", (field_path,))

样本记录:

a.extbootrecord.field_db0    
a.extbootrecord.field_db1    
a.extbootrecord.field_db8    
a.extbootrecord.field_db9    
a.extbootrecord.field_db10   
a.extbootrecord.field_db11   
a.extbootrecord.field_db12   
a.extbootrecord.field_db15   

使用以下查询:

db_cursor.execute("select full_path from field_names where field_names = '\"%s\"'" % search_phrase)
return_list = list()

entries = db_cursor.fetchmany(100)
while entries:
    return_list.extend([entry[0] for entry in entries])
    entries = db_cursor.fetchmany(100)

以下search_phrase会产生以下内容:

  1. ext:没有
  2. extbootrecord:所有记录
  3. extbootrecrd.:所有记录
  4. extbootrecord.fie:没有
  5. extbootrecord.field:所有记录
  6. extbootrecord.field_db1:仅a.extbootrecord.field_db1条记录,我希望返回field_db1,field_db10,field_db11 ...
  7. 似乎我错过了一些FTS配置,将._0-9作为有效字符作为令牌的一部分使用。

    我尝试在创建语句中使用tokenize = \"unicode61 tokenchars '_.'\"配置FTS标记生成器,但没有运气。

    我错过了什么?

3 个答案:

答案 0 :(得分:0)

刚刚在不同的平台上遇到了同样的问题。这种语法对我有用:

tokenize=unicode61 \"tokenchars=_.\"

答案 1 :(得分:0)

这里有一个完整的例子可以说明tokenchars的工作原理,因为我认为语法相当微妙,容易出错。

让我们首先在shell中创建测试环境:

$ sqlite3 ":memory:"

现在让我们创建一个fts5 table来允许句点:

sqlite> CREATE VIRTUAL TABLE IF NOT EXISTS foo USING fts5(name UNINDEXED, keywords, tokenize="unicode61 tokenchars '.'");

请注意如何设置tokenize的值,在该值上用双引号引起来,在要添加的tokenchars上用单引号引起来(我们只是在此处添加句点,但您可以添加为许多字符)。

准备好我们的表后,我们准备插入一些值:

sqlite> INSERT INTO foo (name, keywords) VALUES ('bar', '1.0');
sqlite> INSERT INTO foo (name, keywords) VALUES ('che', '1.5');
sqlite> INSERT INTO foo (name, keywords) VALUES ('baz', '2.5');

并搜索这些值:

sqlite> SELECT name from foo WHERE keywords MATCH '"1."*';
bar
che
sqlite> SELECT name from foo WHERE keywords MATCH '"1.5"*';
che
sqlite> SELECT name from foo WHERE keywords MATCH '"2"*';
baz 

请注意,如果我们在搜索字符串中有句点,则必须如何搜索值,我们必须将搜索字符串用双引号引起来(如果要进行前缀搜索,则必须在这些双引号之外添加星号),然后照常将整个字符串用单引号引起来。

如果我们不使用双引号:

sqlite> SELECT name from foo WHERE keywords MATCH '1.*';
Error: fts5: syntax error near "."

或者我们错误地使用了双引号:

sqlite> SELECT count(*) from foo WHERE keywords MATCH '1"."*';
0

然后,我们将获得含糊不清的无用错误和出乎意料的结果,这将导致我们在互联网上搜索,试图弄清楚我们在做错什么,并绊倒了这个问题:)

答案 2 :(得分:0)

使用FTS4可以使用“。”搜索