2

我需要将 FTS 添加到现有数据库中。

开始测试外部内容 FTS 表,其中 FTS 索引驻留在默认(主)数据库中。一切都令人满意,除了一些事情(例如索引重建)可能需要相当长的时间。

然后我读到了将 FTS 索引放入附加数据库的可能性。这似乎有几个好处,因此我决定试一试。然而,我所有的尝试都失败了。这里有一些例子:

情况

  • 我们有一个带有文本列“代码”的表“帐户”,并且

  • 想要为该列创建 FTS 索引并将其放入单独的数据库文件中

Test1) ERROR: near ".": 语法错误

ATTACH 'ZipFts.sdf' AS ZipFts; CREATE VIRTUAL TABLE ZipFts.account USING fts4(content=account, code);
INSERT INTO ZipFts.account(ZipFts.account) VALUES('rebuild');

测试 2)错误:堆栈溢出(sqlite 引擎内的无限递归)

ATTACH 'ZipFts.sdf' AS ZipFts; CREATE VIRTUAL TABLE ZipFts.account USING fts4(content=account, code);
INSERT INTO ZipFts.account(account) VALUES('rebuild');

Test3)错误:没有这样的表:ZipFts.account

ATTACH 'ZipFts.sdf' AS ZipFts; CREATE VIRTUAL TABLE ZipFts.ZipFts_account USING fts4(content="account", code);
INSERT INTO ZipFts_account(ZipFts_account) VALUES('rebuild');

Test4)错误:没有这样的表:ZipFts.main.account

ATTACH 'ZipFts.sdf' AS ZipFts; CREATE VIRTUAL TABLE ZipFts.ZipFts_account USING fts4(content="main.account", code);
INSERT INTO ZipFts_account(ZipFts_account) VALUES('rebuild');

有人知道这些东西是如何工作的吗?提前致谢。

4

2 回答 2

1

在 sqlite3.c 中进行一些搜索后,我发现了可能的答案。

查看函数 fts3ReadExprList() 的底部。内容表的名称在此处以 DB 名称为前缀!这解释了一切。

此外,这似乎是 zContentTbl(= 内容表的名称)的唯一重要用途。当我稍微修改 fts3ReadExprList() 函数(如下面的代码所示)时,问题就消失了。

  // Code inserted by @JS-->
  // Do not prefix zContentTbl with the database name. The table might reside in main database, for example.
  if( p->zContentTbl){
    fts3Appendf(pRc, &zRet, " FROM '%q' AS x", p->zContentTbl);
  }
  else
  // <--@JS
  fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", 
  ...

请注意,我没有充分测试代码。(目前我只知道创建了 FTS 索引。)

无论如何,目前,我认为这是一个 SQLite 错误,我将尝试继续进行修复。

于 2013-04-24T13:09:24.953 回答
0

我认为这是设计的。

如果不是这样,外部内容表的基础表可能会随着数据库的附加或分离而改变。

不过,您也许可以使用无内容的 FTS 表来实现这一点。

丹肯尼迪。

于 2013-04-24T14:12:58.413 回答