SQLite FTS4使用首选语言

Pea*_*ach 6 sqlite full-text-search materialize

我有一个使用FTS4模块生成的SQLite表.每个条目至少列出两次使用不同的语言,但仍然共享一个唯一的ID(int列,未编入索引).这是我想要做的:我想用首选语言查找一个术语.我想将结果与使用其他语言查找同一个术语结合起来.但是对于第二次查找,我想忽略我在第一次查找期间找到的所有条目(由它们的ID标识).所以基本上我想这样做:

WITH term_search1 AS (
    SELECT *
    FROM myFts
    WHERE myFts MATCH 'term'
    AND languageId = 1)
SELECT *
FROM term_search1
UNION
SELECT *
FROM myFts
WHERE myFts MATCH 'term'
AND languageId = 2
AND id NOT IN (SELECT id FROM term_search1)
Run Code Online (Sandbox Code Playgroud)

这里的问题是,term_seach1查询将被执行两次.有没有办法实现我的结果呢?将其限制为2个查询(而不是3个)的任何解决方案都会很棒.

我也尝试过使用递归查询,例如:

WITH RECURSIVE term_search1 AS (
    SELECT *
    FROM myFts
    WHERE myFts MATCH 'term'
    AND languageId = 1
UNION ALL
    SELECT m.*
    FROM myFts m LEFT OUTER JOIN term_search1 t ON (m.id = t.id)
    WHERE myFts MATCH 'term'
    AND m.languageId = 2
    AND t.id IS NULL
)
SELECT * FROM term_search1
Run Code Online (Sandbox Code Playgroud)

这既不起作用.显然他刚刚为languageId = 2执行了两次查找(这可能是一个错误吗?).

提前致谢 :)

Par*_*ras 4

您可以使用 TEMPORARY 表将对 myFts 的查询数量减少到 2:

CREATE TEMP TABLE results (id INTEGER PRIMARY KEY);

INSERT INTO results 
    SELECT id FROM myFts
    WHERE myFts MATCH 'term' AND languageId = 1;

INSERT INTO results
    SELECT id FROM myFts
    WHERE myFts MATCH 'term' AND languageId = 2
    AND id NOT IN (SELECT id FROM results);

SELECT * FROM myFts
    WHERE id IN (SELECT id FROM results);

DROP TABLE results;
Run Code Online (Sandbox Code Playgroud)

如果可以更改架构,则应仅在 FTS 表中保留文本数据。这样,当您搜索数字并且languageId不需要匹配的行时,您可以避免错误的结果。创建另一个包含非文本数据(如id和)的元表,并通过连接的languageId来过滤行。这样,您只需查询 FTS 表一次- 使用临时表存储 FTS 表结果,然后使用元表对它们进行排序。rowidmyFts