全文搜索(Full-Text-Search,简称 FTS),是 SQLite 提供的功能之一。它支持更快速、更便捷地搜索数据库内的信息,常用于应用内的全局搜索等功能。

WCDB Swift 内建了全文搜索的支持,对中文、日文等非空格分割的语言做了针对性的优化;对英文做了词性还原,使搜索不受词形、时态的限制;从而使搜索更加精确。

虚拟表映射

虚拟表是 SQLite 的一个特性,可以更自由地自定义数据库操作的行为。在模型绑定一章,我们提到了虚拟表映射,但没有具体介绍。而在全文搜索中,它是不可或缺的一部分。

  1. class SampleFTS: TableCodable {
  2. var summary: String? = nil
  3. var description: String? = nil
  4.  
  5. enum CodingKeys: String, CodingTableKey {
  6. typealias Root = SampleFTS
  7. static let objectRelationalMapping = TableBinding(CodingKeys.self)
  8. case summary
  9. case description
  10. static var virtualTableBinding: VirtualTableBinding? {
  11. return VirtualTableBinding(with: .fts3, and: ModuleArgument(with: .WCDB))
  12. }
  13. }
  14. }
  15.  
  16. try database.create(virtualTable: "sampleVirtualTable", of: SampleFTS.self)

全文搜索的虚拟表映射一般只需定义模块和分词器即可。而若无特殊需求,使用 FTS3 和 WCDB 分词器即可。定义完成后,调用 create(virtualTable:of:) 接口,则会根据字段映射和虚拟表映射创建虚拟表。

建立索引

全文搜索的速度依赖于其索引。

  1. let english = SampleFTS()
  2. english.summary = "WCDB is a cross-platform database framework developed by WeChat."
  3. english.description = "WCDB is an efficient, complete, easy-to-use mobile database framework used in the WeChat application. It can be a replacement for Core Data, SQLite & FMDB."
  4.  
  5. let chinese = SampleFTS()
  6. chinese.summary = "WCDB 是微信开发的跨平台数据库框架"
  7. chinese.description = "WCDB 是微信中使用的高效、完整、易用的移动数据库框架。它可以作为 CoreData、SQLite 和 FMDB 的替代。"
  8.  
  9. try database.insert(objects: english, chinese, intoTable: "sampleVirtualTable")

建立索引的操作与普通表插入数据基本一致。

根据索引查找数据

全文搜索与普通表不同,必须使用 match 函数进行查找。

  1. let objectMatchFrame: SampleFTS? = try database.getObject(from: "sampleVirtualTable", where: SampleFTS.Properties.summary.match("frame*"))
  2. print(objectMatchFrame.summary) // 输出 "WCDB is a cross-platform database framework developed by WeChat."
  3.  
  4. // 词形还原特性,通过 "efficiency" 也可以搜索到 "efficient"
  5. let objectMatchEffiency: Sample? = try database.getObject(from: "sampleVirtualTable", where: SampleFTS.Properties.description.match("efficiency"))
  6. print(objectMatchEffiency.summary) // 输出 "WCDB is an efficient, complete, easy-to-use mobile database framework used in the WeChat application. It can be a replacement for Core Data, SQLite & FMDB."
SQLite 分词必须从首字母查起,如"frame",而类似"amework"这样从单词中间查起是不支持的。

全表查询

全文搜索中有一列隐藏字段,它与表名一致。通过它可以对全表的所有字段进行查询。

  1. let tableColumn = Column(named: "sampleVirtualTable")
  2.  
  3. let objects: [SampleFTS] = try database.getObject(from: "sampleVirtualTable", where: tableColumn.match("SQLite"))
  4.  
  5. print(objects[0].description) // 输出 "WCDB is an efficient, complete, easy-to-use mobile database framework used in the WeChat application. It can be a replacement for Core Data, SQLite & FMDB."
  6. print(objects[1].description) // 输出 "WCDB 是微信中使用的高效、完整、易用的移动数据库框架。它可以作为 CoreData、SQLite 和 FMDB 的替代。"