【问题标题】:SQL FTS3 Doesn't Seem To Add Content FTS4 DoesSQL FTS3 似乎没有添加 FTS4 的内容
【发布时间】:2015-08-04 23:40:11
【问题描述】:

我正在尝试在我现有的 SQLite 数据库中使用 FTS,因此我将 external source 用于虚拟表 - 但我得到了一个 FTS3 表的令人困惑的结果,我将结束必须使用if I plan on supporting < 11 Android API

在我的 DB Contract 类的这个静态函数中,我为 SQL 创建初始化字符串以创建我的虚拟表。

数据库合同:

public static String getVirtualCreate(){
    if (VIRTUAL_TABLE_NAME == "")
        return "";
    String createstring = "CREATE VIRTUAL TABLE IF NOT EXISTS " + VIRTUAL_TABLE_NAME + " USING fts4(content=\"" + TABLE_NAME +"\",";
    for (int a = 0; a < virtualCount(); a++){
        createstring += getVirtualColumn(a).getName();
        if (a < count() - 1){
            createstring += ",";
        }
    }
    createstring += ")";
    return createstring;
}

以及创建触发器的这段代码

public static String getVirtualCreateTriggers(){

    String rowstring = "";
    String postrowstring = "";

    for(int a = 0; a < virtualCount(); a++){
        rowstring += getVirtualColumn(a);
        postrowstring += "new." + getVirtualColumn(a);

        if (a < virtualCount() - 1){
            rowstring += ",";
            postrowstring += ",";
        }
    }

    String ret =
            "CREATE TRIGGER IF NOT EXISTS TABLE_NAME_bu BEFORE UPDATE ON TABLE_NAME BEGIN\n" +
                    "  DELETE FROM VIRTUAL_TABLE_NAME WHERE docid=old."+COLUMN_NAME_ID+";\n" +
                    "END;\n" +
                    "CREATE TRIGGER TABLE_NAME_bd BEFORE DELETE ON TABLE_NAME BEGIN\n" +
                    "  DELETE FROM VIRTUAL_TABLE_NAME WHERE docid=old."+COLUMN_NAME_ID+";\n" +
                    "END;\n" +
                    "CREATE TRIGGER TABLE_NAME_au AFTER UPDATE ON TABLE_NAME BEGIN\n" +
                    "  INSERT INTO VIRTUAL_TABLE_NAME(docid,"+rowstring+") VALUES("+postrowstring+");\n" +
                    "END;\n" +
                    "CREATE TRIGGER TABLE_NAME_ai AFTER INSERT ON TABLE_NAME BEGIN\n" +
                    "  INSERT INTO VIRTUAL_TABLE_NAME(docid, "+rowstring+") VALUES("+postrowstring+");\n" +
                    "END;";

    return ret;
}

数据库助手:

DBContract 创建字符串似乎在实现中运行良好。如果我打电话给:

Cursor mCursor = db.rawQuery("SELECT * FROM " + DbContract.PartEntry.VIRTUAL_TABLE_NAME ,null);

它将返回原始表的所有值。

但是,如果我调用完全相同的代码,但将 CreateString 更改为 FTS3

String createstring = "CREATE VIRTUAL TABLE IF NOT EXISTS " + VIRTUAL_TABLE_NAME + " USING fts3(content=\"" + TABLE_NAME +"\",";

即使在虚拟表更改后添加了额外的行 SELECT * 返回 0 行。

改回来后一切正常。

其次,如果我使用像 Cursor mCursor = db.rawQuery("SELECT * FROM " + DbContract.PartEntry.VIRTUAL_TABLE_NAME + " WHERE " + DbContract.PartEntry.VIRTUAL_TABLE_NAME + " match '" + search + "'",null); 这样的函数,可能是相关的

search 是一个(暂时未转义)字符串,它在原始 AND 虚拟表中最明确地找到(通过 select * 验证)它为 FTS4 返回 0 行,目前在 FTS3 中无法测试,因为前面提到的问题,没有出现数据。

问题:

我是否在表定义中做错了什么?或者也许还有其他可能导致 FTS3 中的通配符搜索不返回任何结果,似乎没有抛出任何错误消息?不幸的是,这是我第一次接触香草 SQL 之外的任何东西,所以我很可能在某处做错了什么。

如果我没有足够的代码或足够好的示例,是否可以添加更好的示例或更相关的代码来帮助更好地了解情况?

【问题讨论】:

  • 修复了一个问题,以便在 FTS4 表上使用 match 我需要重建索引 INSERT INTO vtable(vtable) VALUES('rebuild');
  • Shoot... 又仔细看了一遍手册,看起来外部内容是 FTS4 独有的选项之一... 问题 #2 已解决。

标签: android sqlite full-text-search


【解决方案1】:

我不喜欢自己回答问题...但是经过一番困惑后,我发现了我的两个问题的答案。

FTS4 match 请求返回 0 行的原因是它没有被索引。

修复:

INSERT INTO vtable(vtable) VALUES('rebuild');

将表定义从 FTS4 更改为 FTS3 无法正常运行的原因是使用外部内容的选项(至少据我所知)是 FTS4 独有的选项。这意味着它在 FTS3 上不可用..

我的解决方案是构建两个版本的虚拟表,一个用于 API 11 之前的 FTS3,没有外部源,另一个使用 FTS4,允许我们使用外部源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    相关资源
    最近更新 更多