iphone - 如何优化全文搜索的 Core Data 查询

标签 iphone sql cocoa cocoa-touch core-data

在文本中搜索匹配的单词时,我可以优化核心数据查询吗? (这个问题也涉及到 iPhone 上自定义 SQL 与 Core Data 的区别。)

我正在开发一款新的 (iPhone) 应用程序,它是科学数据库的手持引用工具。主界面是一个标准的可搜索表格 View ,我希望在用户输入新单词时得到即时响应。单词匹配必须是文本中单词的前缀。该文本由 100,000 个单词组成。

在我的原型(prototype)中,我直接编写了 SQL 代码。我创建了一个单独的“单词”表,其中包含主实体文本字段中的每个单词。我对单词进行了索引并按照以下方式执行了搜索

SELECT id, * FROM textTable 
  JOIN (SELECT DISTINCT textTableId FROM words 
         WHERE word BETWEEN 'foo' AND 'fooz' ) 
    ON id=textTableId
 LIMIT 50

这运行得非常快。使用 IN 可能也同样有效,即

SELECT * FROM textTable
 WHERE id IN (SELECT textTableId FROM words 
               WHERE word BETWEEN 'foo' AND 'fooz' ) 
 LIMIT 50

LIMIT 至关重要,它可以让我快速显示结果。我通知用户,如果达到限制,则显示太多。这很糟糕。

过去几天我一直在思考迁移到核心数据的优势,但我担心重要查询的架构、索引和查询缺乏控制。

理论上,textField MATCHES '.*\bfoo.*' 的 NSPredicate 就可以工作,但我确信它会很慢。这种文本搜索似乎很常见,我想知道通常的攻击是什么?您会像我上面那样创建一个单词实体并使用“word BEGINSWITH 'foo'”谓词吗?它会像我的原型(prototype)一样快吗? Core Data 会自动创建正确的索引吗?我找不到任何明确的方法来向持久存储提供有关索引的建议。

我在我的 iPhone 应用程序中看到了 Core Data 的一些很好的优势。故障和其他内存考虑因素允许对 TableView 查询进行高效的数据库检索,而无需设置任意限制。对象图管理使我能够轻松遍历实体,而无需编写大量 SQL。将来迁移功能会很好。另一方面,在有限的资源环境(iPhone)中,我担心自动生成的数据库会因为元数据、不必要的逆关系、低效的属性数据类型等而变得臃肿。

我应该一头扎进去还是谨慎行事?

最佳答案

我制定了一个解决方案。我认为它类似于 this post 。我将合并源代码添加到我的 Core Data 项目中,然后创建一个不是托管对象子类的全文搜索类。在FTS类中,我#import "sqlite3.h"(源文件)而不是sqlite框架。 FTS 类保存到与 Core Data 持久存储不同的 .sqlite 文件。

当我导入数据时,Core Data 对象将相关 FTS 对象的 rowid 存储为整数属性。我有一个静态数据集,因此我不担心引用完整性,但维护完整性的代码应该很简单。

为了执行 FTS,我 MATCH 查询 FTS 类,返回一组 rowid。在我的托管对象类中,我使用 [NSPredicate predicateWithFormat:@"rowid IN %@", rowids] 查询相应的对象。我避免以这种方式遍历任何多对多关系。

性能提升非常显着。我的数据集有 142287 行,包括 194MB(核心数据)和 92MB(删除停用词的 FTS)。根据搜索词频率的不同,我的搜索时间从几秒缩短到 0.1 秒(对于不常见术语(<100 次点击))和 0.2 秒(对于频繁术语(>2000 次点击))。

我确信我的方法存在无数问题(代码膨胀、可能的命名空间冲突、丢失一些核心数据功能),但它似乎有效。

关于iphone - 如何优化全文搜索的 Core Data 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1774369/

相关文章:

iphone - 是否可以配置 UITableView 以允许多重选择?

iphone - <错误> : CGAffineTransformInvert: singular matrix

sql - 根据列值将数据划分到不同的表中是否合理?

mysql - 连接两个表以获取第二个表中的所有数据

objective-c - 无论如何要在 objective-c 中快速将单词分解为字符数组?

iphone - 如何使用 fb ://url 从其他应用程序打开 iphone fb 应用程序中的照片

iphone - 如何获取 JSON 值?

php - SQL 查询 OR 和 AND

macos - NSWindow 控制多个选项卡

cocoa - 在基于文档的 Cocoa 应用程序中扩展自定义分页