【问题标题】:Room 2.1 SQLite FTS: inserting new single FTS object in databaseRoom 2.1 SQLite FTS:在数据库中插入新的单个 FTS 对象
【发布时间】:2020-06-01 09:12:04
【问题描述】:

我一直在尝试使用 FTS 表的新 Android 房间 2.1 功能来启用搜索功能。

实体:

 @Entity
    class ChatMessageEntity(
            @PrimaryKey
            var messageId: String,
            var messageUser: String,
            var messageText: String,
            )

FTS 实体:

@Fts4(contentEntity = ChatMessageEntity::class)
@Entity
class ChatMessageFts(
        var messageText: String //only want messageText searchable
)

数据库:

@Database(entities = [ChatMessageEntity::class, ChatMessageFts::class], version = 1)
abstract class ChatMessageDatabase : RoomDatabase() {

    abstract fun chatMessageDatabase(): ChatMessageDao

    companion object {
        fun create(context: Context) = Room.databaseBuilder(context, ChatMessageDatabase::class.java, DB_NAME).build()
    }
}

DAO:

@Query("INSERT INTO ChatMessageFts(ChatMessageFts) VALUES('rebuild')") //works
    suspend fun ftsRebuild()

@Query("INSERT INTO ChatMessageFts(docid, messageText) VALUES(:id, :text)") //compiles but doesn't work
    suspend fun saveFtsMessage(id: Long, text: String)

当我还在原始表中添加行时,我希望在 FTS 中添加每一行(ChatMessageEntity - 未显示)。从头开始重建 FTS 表时,它工作得很好(上面的ftsRebuild())。

但是,我希望单独添加每个输入。我已经尝试了很多东西(例如上面显示的saveFtsMessage()) - 不带 docId 添加,尝试使用 rowId,...我什至尝试将新对象 ChatMessageEntity 添加到 ChatMessageFts 作为输入,但我没有设法编译这是由于错误。

欢迎任何关于如何在 FTS 表中添加个人输入的建议!

【问题讨论】:

  • 你不应该需要这些INSERT INTO ChatMessageFts 语句中的任何一个。插入ChatMessage 将通过触发器填充ChatMessageFts
  • @CommonsWare 非常感谢。不知道我以前怎么没有意识到这一点。你认为我应该关闭这个问题还是将你的答案标记为已接受(如果是,请在下面添加)?

标签: android sqlite full-text-search android-room fts4


【解决方案1】:
@Fts4(contentEntity = ChatMessageEntity::class)

注解的contentEntity 属性的神奇之处在于Room 设置触发器以使您的FTS 表与相应的实体表保持同步:

"contentSyncTriggers": [
  "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_paragraphsFts_BEFORE_UPDATE BEFORE UPDATE ON `paragraphs` BEGIN DELETE FROM `paragraphsFts` WHERE `docid`=OLD.`rowid`; END",
  "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_paragraphsFts_BEFORE_DELETE BEFORE DELETE ON `paragraphs` BEGIN DELETE FROM `paragraphsFts` WHERE `docid`=OLD.`rowid`; END",
  "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_paragraphsFts_AFTER_UPDATE AFTER UPDATE ON `paragraphs` BEGIN INSERT INTO `paragraphsFts`(`docid`, `prose`) VALUES (NEW.`rowid`, NEW.`prose`); END",
  "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_paragraphsFts_AFTER_INSERT AFTER INSERT ON `paragraphs` BEGIN INSERT INTO `paragraphsFts`(`docid`, `prose`) VALUES (NEW.`rowid`, NEW.`prose`); END"
]

(来自this sample app来自this book

只要您插入、更新和删除实体,FTS 表就会自动维护。您只需使用 FTS 表进行查询。

如果您跳过 contentEntity 注释并假设它有效,那么您可能需要独立维护您的 FTS 表。

【讨论】:

    猜你喜欢
    • 2020-03-05
    • 2015-03-05
    • 2014-10-30
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多