尽管苹果有一个现成的全文搜索解决方案,形式为搜索套件,但它有几个主要的缺点。
目前有几个解决此问题的方案,但它们并不完美
这就是LevelSearch发挥作用的地方。它设计得易于集成,同时保持最低的影响(没有objc/runtime或相关对象),并提供了可以满足需要如自动完成这样的低延迟用例的全文搜索的性能。
正如其名所示,LevelSearch是基于Google开发的LevelDB键/值数据库构建的,该数据库采用BSD许可发布。它是一个高性能键/值存储,类似于Redis,但它针对的是嵌入式客户端用途,例如Chrome浏览器,这使得它在这种用例中非常棒。有关更多信息,您可以先看看Google的文档。
这表示 LevelSearch 使用每个索引的 LevelDB 实例,其基于文件支持自行持久化。LevelSearch 支持单个共享便利索引或多个命名索引——如何最有效地利用它完全取决于您的用例。
尽管 LevelSearch 在技术上使用了一些功能,但它真的非常容易使用,因为它使用 Core Data 保存通知来管理所有的索引更改。一旦它开始监视某个 NSManagedObjectContext
,索引将愉快地继续索引和更新索引,一旦检测到 Core Data 的更改。这种紧密耦合使得 Level Search 非常流线型,实现相当精简,大约 500 LOC(不包括 LevelDB 库和 Objective-C 封装)。
它也非常快,更多相关信息请见下面的基准。
之后,只需导入共享头文件即可。
#import <LevelSearch/LevelSearch.h>
使用 LevelSearch 非常简单,您只需配置索引,其余的都由它来处理。
如果您只需要单个索引,则共享索引效果很好。要在 Core Data 配置完成后设置它,请按照以下步骤进行:
[[LSIndex sharedIndex] addIndexingToEntity:[NSEntityDescription entityForName:@"ExampleEntity" inManagedObjectContext:ExampleContext] forAttributes:@[@"attribute1", @"attribute2"]];
[[LSIndex sharedIndex] startWatchingManagedObjectContext:ExampleContext];
这确实非常简单。尽管如此,需要注意的是,由于 LevelSearch 不使用任何运行时技巧,它无法向您的托管对象添加任何类型的键。这在大多数情况下是个好事,但鉴于 Core Data 提供的唯一真实主键是 NSManagedObjectID,因此需要在将对象保存到持久存储之前将其索引(因为对象 ID 是临时的并且可以更改,直到对象被保存)。
这意味着您应该监视直接连接到 NSPersistentStoreCoordinator 的 NSManagedObjectContext,而不是子上下文。如果您只使用一个上下文,例如苹果的默认 Core Data 代码,则没问题;如果您使用 MagicalRecord(或类似使用主线程上下文和父保存上下文的堆栈)则想要这样做:
[[LSIndex sharedIndex] startWatchingManagedObjectContext:[NSManagedObjectContext MR_rootSavingContext]];
配置索引后,您真的不需要做任何事情,索引将注册 Core Data 保存通知并通过 Core Data 自动索引对象。如果您想要更精细地控制索引何时发生,则可以使用 LSIndexDelegate
协议或通知。这两个都提供完整文档。
有两种查询方法:同步和异步查询方法。对于大多数人来说,异步方法被广泛采用,因为您不希望在用户输入搜索词时主线程有延迟。同步方法对于测试有帮助,如果您想要拥有自己的搜索队列,则可以自行实现异步搜索,但请做好善事,请不要从主线程调用这些方法。
在其他方面,同步和异步查询之间的查询接口是相同的,一个简单的查询如下:
[[LSIndex sharedIndex] queryInBackgroundWithString:@"example query"
withResults:^(NSSet *results) {
// Put your completion code here...
}];
查询返回的结果是 Core Data 对象的 NSSet
,您甚至不需要执行自己的 NSFetchRequest
...查询已经为您处理了一切。您可能想要使用 NSSortDescriptor
将结果排序成一个 NSArray
,但这非常直观。
要运行示例项目;首先克隆仓库,然后从根目录运行pod install
。有两个示例应用程序:一个用于展示如何集成框架,另一个用于性能和集成测试。
John Tumminaro, [email protected]
LevelSearch遵循MIT许可。更多信息请参阅LICENSE文件。