iOS 中的全文子字符串搜索

Posted

技术标签:

【中文标题】iOS 中的全文子字符串搜索【英文标题】:Full-Text Substring Searching in iOS 【发布时间】:2011-07-18 08:09:51 【问题描述】:

我需要我的 iPhone / iPad 应用程序能够快速搜索大约 10,000 条记录(每条记录大约相当于一段文本),以查找记录中包含的任何子字符串。因此,如果记录包含单词“Flame”,则查询“lame”应该匹配。

我目前正在使用 SQLite,但是“LIKE %term%”搜索对于这么多记录来说太慢了。启用全文搜索似乎不能完全满足我的需求,因为 SQLite 只支持前缀通配符(例如“Flam*”,而不是“*lame”)。

我已经尝试过使用一个巨大的文本块 (~350K),并执行 [NSString rangeOfString:...],我认为它使用了 Boyer-Moore 算法。这比“LIKE %term%”搜索要快,但仍然不是我希望的那种速度。

对于可以实现这种可扩展子字符串搜索并且适用于 iPhone 的方法或库有什么建议吗?

【问题讨论】:

我有一个类似的数据集/查询问题,我发现我必须使用 UI 和线程技巧来让它感觉响应。我在一个工作线程中进行了所有搜索,这将在用户键入时取消/重新运行搜索。我没有找到灵丹妙药。 感谢 NWCoder。我也考虑过这种异步方法。除此之外,您选择哪种方法进行搜索? LIKE 查询? 是的,我只能通过 LIKE 获得正确的结果。还有一点需要注意的是,我最终创建了一个简单的对象,其中只有可搜索的文本和一个引用对象扩展属性的 ID。在搜索特定版本中,我对文本进行了规范化(所有小写无标点符号等),它有所帮助,但作用不大。 (可能会提高 5-10% 的速度。) 【参考方案1】:

这里有许多不同的选项。我不知道每个的基准,所以你必须做一些测试。

首先是 SQLite 的 FTS3 扩展。这应该为您提供快速的索引全文搜索: http://regularrateandrhythm.com/regular-rate-rhythm-blog/sqlite3-fts-in-ios4.html

那么,iOS 4 中引入的正则表达式怎么样:http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html

对于 iOS 4 之前的版本,您可以使用 RegexKitLite:http://regexkit.sourceforge.net/RegexKitLite/index.html

如果您决定使用正则表达式,请查看此条目以了解如何优化它们:How to speed up iPhone regular expressions with NSRegularExpression?

【讨论】:

正则表达式很慢...我确定您需要某种索引 O(1) 解决方案。如果您自己推出或通过 SQLite 找到一个好的解决方案,很想听听... 是的,Regex 比常规文本搜索要慢得多。正如我最初写的那样,SQLite 中的全文搜索并不能满足我的要求。【参考方案2】:

也许考虑将您的第二种方法与异步方法结合起来。将您的大文本块分成 5,10,无论大小,并使用相同数量的线程分别搜索它们。然后通过使用知道如何正确定位匹配项的坐标系来组合结果(例如,线程 5 搜索区域 5 并在位置 337 找到与文档 x、位置 y 相关的匹配项)。您会发现添加更多线程没有好处是有限制的,因此首先要弄清楚这一点。

【讨论】:

【参考方案3】:

如果您无法对文本进行标记(将其拆分为单词),则无法对其进行索引。这就是 LIKE 是顺序搜索的原因。除非您的子字符串可以以某种方式受到约束(例如,总是删除第一个字母或子字符串的固定长度),否则您的文本不能存储为所有可能标记的列表,并且这些标记不能被索引。关键(双关语)是找到一种算法,该算法产生足够小的标记列表,索引它们的成本低于线性搜索的成本。

【讨论】:

以上是关于iOS 中的全文子字符串搜索的主要内容,如果未能解决你的问题,请参考以下文章

Python:在字符串列表中最佳搜索子字符串

如何搜索子字符串(WHERE列LIKE'%foo%')

在区域下添加子文件夹并配置视图引擎以搜索子文件夹中的视图

sql MSSQL搜索子字符串

Gcloud 日志查看器 - 搜索子字符串过滤器不起作用

iOS 中的全文子字符串搜索