标签: fts4

如何通过另一个表中的字段获得更快的FTS4查询结果?

背景

我正在对存储在SQLite中的一组电子邮件进行全文搜索,利用其出色的内置FTS4引擎.虽然不完全符合我的预期,但我的查询性能相当差.让我们来看看.

代表架构

我将提供一些有关代码的简化示例,并在适用的地方提供完整代码的链接.

我们有一个MessageTable存储有关电子邮件消息的数据(完整版本分布在几个文件,这里,这里这里):

CREATE TABLE MessageTable (
    id INTEGER PRIMARY KEY,
    internaldate_time_t INTEGER
);
CREATE INDEX MessageTableInternalDateTimeTIndex
    ON MessageTable(internaldate_time_t);
Run Code Online (Sandbox Code Playgroud)

可搜索的文本被添加到名为MessageSearchTable(此处为完整版)的FTS4表中:

CREATE VIRTUAL TABLE MessageSearchTable USING fts4(
    id INTEGER PRIMARY KEY,
    body
);
Run Code Online (Sandbox Code Playgroud)

id搜索表作为一个外键消息表.

我将把它作为练习让读者在这些表格中插入数据(我当然不能透露我的私人电子邮件).我每张桌子的记录不到26k.

问题查询

当我们检索搜索结果时,我们需要按顺序对它们进行排序,internaldate_time_t这样我们才能获取最新的几个结果.这是一个示例搜索查询(此处为完整版):

SELECT id
FROM MessageSearchTable
JOIN MessageTable USING (id)
WHERE MessageSearchTable MATCH 'a'
ORDER BY internaldate_time_t DESC
LIMIT 10 OFFSET 0
Run Code Online (Sandbox Code Playgroud)

在我的机器上,通过我的电子邮件,运行大约150毫秒,通过以下方式测量:

time …
Run Code Online (Sandbox Code Playgroud)

sqlite fts3 fts4

14
推荐指数
1
解决办法
3994
查看次数

如何在Windows上使用python2.7设置FTS3/FTS4

默认情况下,FTS3/FTS4在python中不起作用(最多2.7).我收到错误:

sqlite3.OperationalError: no such module: fts3
要么

sqlite3.OperationalError: no such module: fts4

怎么解决这个问题?

python sqlite full-text-search fts3 fts4

12
推荐指数
1
解决办法
5158
查看次数

使用带有OR运算符的多个标记使用全文搜索(FTS)在多列中搜索

我正在使用FTS查询我的数据库以提高搜索速度,因为我还需要在文本描述中搜索,

当我尝试使用单列进行查询时,其工作正常如下

select * from productsearch where productsearch match ('prod_name:panasonic*tw*')
Run Code Online (Sandbox Code Playgroud)

并且,

select * from productsearch where productsearch match ('prod_short_desc:samsung*s5*')
Run Code Online (Sandbox Code Playgroud)

所以,在两个查询之上给出了我预期的结果,但是当我尝试使用OR运算符组合两个查询时它没有给我任何结果

select * from productsearch where productsearch match ('prod_name:panasonic*tw* OR
                                                         prod_short_desc:samsung*s5*')
Run Code Online (Sandbox Code Playgroud)

所以,我想在使用OR运算符搜索多个列时知道我在这里做错了什么

UPDATE

以下查询工作正常,但不符合我的要求,

select * from productsearch where productsearch match ('prod_name:panasonic* OR 
                                                            prod_short_desc:samsung*')
Run Code Online (Sandbox Code Playgroud)

您可以看到,如果我删除多个令牌,那么它也可以与OR运算符一起正常工作.

sqlite android full-text-search fts4

8
推荐指数
1
解决办法
961
查看次数

iOS SQLite全文搜索示例

我正在尝试构建一个使用SQLite FTS的应用程序.我发现了一篇关于如何按照我想要的方式做到这一点的非常有趣的帖子.但是,我根本不是一个非常有经验的程序员,特别是在本文中使用的CoreData中.是否有任何示例项目与本文中描述的内容类似?看看在上下文中做了什么,这对我有很大的帮助.我很抱歉,如果这是一个愚蠢的问题,我对这一切仍然是如此新鲜.感谢您的帮助!

以下是该文章的链接:http://blog.lunatech.com/2013/01/24/ios-core-data-sqlite-full-text-search

sqlite core-data fts3 ios fts4

7
推荐指数
1
解决办法
5019
查看次数

如何为 SQLite FTS 查询转义字符串

我正在尝试使用不受信任的用户输入执行 SQLite FTS 查询。我不想让用户访问查询语法,也就是说他们将无法执行像foo OR bar AND cats. 如果他们尝试使用该字符串进行查询,我想将其解释为更像foo \OR bar \AND cats.

SQLite 似乎没有为此内置任何内容,因此我可能最终会构建自己的转义函数,但这似乎很危险且容易出错。有没有首选的方法来做到这一点?

sqlite full-text-search fts4

6
推荐指数
2
解决办法
1754
查看次数

SQLite FTS 中首先是确切的短语,然后才是其他内容?

假设搜索输入是“是什么”。这将匹配“无论它是什么”以及“什么是”,这是确切的短语。现在,如何在排序中将准确的短语排在第一位?

从昨天开始我就一直在思考这个问题,并且不断提出不同的解决方案,但每个解决方案都有其自身的缺陷。

这是我失败的方法(假设输入=“是什么”):

SELECT snippet(fts), 1 as rank
FROM fts
WHERE body MATCH '"what is"'
UNION ALL
SELECT snippet(fts), 2 as rank
FROM fts
WHERE body MATCH 'what* NEAR/3 is*' -- 3 is arbitrary
ORDER BY rank
Run Code Online (Sandbox Code Playgroud)
  • 这一问题的问题是两个 SELECT 不是互斥的,因此会出现重复。
  • 我无法使用 UNION,因为它们在排名列和片段函数上有所不同(第一个将具有 START|what is|END,其他将具有 START|what|ENDSTART|is|END)。
  • 我也不能使用这个(我之前的问题),因为 MATCH 在 ORDER BY 子句中不起作用(因为生成的表/选择不是原始的 FTS 表)。

这是我当前的解决方案:

SELECT snippet(fts)
FROM fts WHERE rowId IN
(
SELECT DISTINCT rowId
FROM 
( 
SELECT rowId, 1 as rank 
FROM fts
WHERE body MATCH '"what …
Run Code Online (Sandbox Code Playgroud)

sql sqlite android fts4

6
推荐指数
1
解决办法
1314
查看次数

SQLite FTS 表是否需要手动填充?

SQLite FTS 的文档暗示应该使用 INSERT、UPDATE、DELETE 等填充和更新 FTS 表。

这就是我正在做的 - 添加行,删除它们等,但最近我注意到,一旦我创建了 FTS 表,它就会使用源中的数据自动填充。我是这样创建的:

CREATE VIRTUAL TABLE notes_fts USING fts4(content="notes", notindexed="id", id, title, body)
Run Code Online (Sandbox Code Playgroud)

如果我在“notes”表中添加一行,它也会自动添加到notes_fts。我想这就是虚拟表。

但是,为什么有一章是关于填充 FTS 表的呢?甚至有什么意义,因为例如,如果我删除一行,如果它仍在源表中,它就会回来。

对此有什么想法吗?FTS 真的需要填充吗?

sqlite full-text-search fts4

6
推荐指数
1
解决办法
1222
查看次数

SQLite FTS4搜索特殊字符

我有一个Android应用程序,它使用FTS4虚拟表在SQLite数据库中搜索数据.它工作正常,但当表中的数据包含特殊字符(如'á','é','í','ó','ú'或'ñ')时,SQLite MATCH函数不会产生任何结果.我此时迷路了.谢谢.

sqlite android full-text-search special-characters fts4

5
推荐指数
1
解决办法
1078
查看次数

SQLite FTS 示例不起作用

我已经下载了最新的 SQLite 3.7.15.2 shell (Win32) 并尝试完全按照http://sqlite.org/fts3.html#section_3上写的那样执行 FTS 示例之一

-- Virtual table declaration
CREATE VIRTUAL TABLE docs USING fts3();

-- Virtual table data
INSERT INTO docs(docid, content) VALUES(1, 'a database is a software system');
INSERT INTO docs(docid, content) VALUES(2, 'sqlite is a software system');
INSERT INTO docs(docid, content) VALUES(3, 'sqlite is a database');

-- Return the set of documents that contain the term "sqlite", and the
-- term "database". This query will return the document with docid 3 only. …
Run Code Online (Sandbox Code Playgroud)

sqlite fts3 fts4

5
推荐指数
1
解决办法
2594
查看次数

Android Room数据库查询不返回id列

问题是查询返回除“ id”以外的所有列

我使用fts4,并在文档中说:

启用了FTS的表始终使用INTEGER类型的主键,并且其列名称为“ rowid”。如果您的FTS表支持的实体定义了主键,则它必须使用该类型和列名。

这是我的实体类:

@Fts4
@Entity(tableName = "projects")
public class Project {

    @ColumnInfo(name = "rowid")
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String name;
    @ColumnInfo(name = "start_date")
    private String startDate;
    @ColumnInfo(name = "end_date")
    private String endDate;
    private String description;
    @ColumnInfo(name = "icon_path")
    private String iconPath;
    private long budget;


public Project(String name, String startDate, String endDate, String description, String iconPath, long budget) {
    this.name = name;
    this.startDate = startDate;
    this.endDate = endDate;
    this.description = description;
    this.iconPath = iconPath;
    this.budget …
Run Code Online (Sandbox Code Playgroud)

sqlite android fts4 android-room

5
推荐指数
1
解决办法
1156
查看次数