如何优化核心数据查询以进行全文搜索

dk.*_*dk. 13 sql iphone cocoa cocoa-touch core-data

在搜索文本中匹配的单词时,我可以优化核心数据查询吗?(这个问题也适用于iPhone上自定义SQL与核心数据的智慧.)

我正在研究一种新的(iPhone)应用程序,它是一个科学数据库的手持式参考工具.主界面是一个标准的可搜索表视图,我想要用户键入新单词时的类型响应.单词匹配必须是文本中单词的前缀.该文本由100,000个单词组成.

在我的原型中,我直接编写了SQL.我创建了一个单独的"单词"表,其中包含主实体文本字段中的每个单词.我索引了单词并按照行进行了搜索

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

这运行得非常快.使用IN可能也会起作用,即

SELECT * FROM textTable
 WHERE id IN (SELECT textTableId FROM words 
               WHERE word BETWEEN 'foo' AND 'fooz' ) 
 LIMIT 50
Run Code Online (Sandbox Code Playgroud)

LIMIT至关重要,可以让我快速显示结果.如果达到限制,我会通知用户显示的内容太多.这是kludgy.

我花了最近几天考虑转移到Core Data的优势,但我担心架构中缺乏控制,索引和查询重要查询.

从理论上讲,NSPredicate textField MATCHES '.*\bfoo.*'会起作用,但我相信它会很慢.这种文本搜索似乎很常见,我想知道通常的攻击是什么?你会像我上面那样创建一个单词实体并使用"bEGINSWITH'foo'这个词的谓词吗?这会像我的原型一样快吗?Core Data会自动创建正确的索引吗?我找不到任何明确的方法来建议持久性存储有关索引.

我在iPhone应用程序中看到了Core Data的一些优点.故障和其他内存注意事项允许对tableview查询进行有效的数据库检索,而无需设置任意限制.对象图管理允许我轻松遍历实体而无需编写大量SQL.移植功能将来会很好.另一方面,在有限的资源环境(iPhone)中,我担心自动生成的数据库会因元数据,不必要的反向关系,低效的属性数据类型等而膨胀.

我应该潜入或谨慎行事吗?

jlu*_*yiv 10

我做了一个解决方案.我认为这与这篇文章类似.我将合并源代码添加到我的Core Data项目中,然后创建了一个不是托管对象子类的全文搜索类.在FTS类I #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次点击).

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