iOS复合谓词

9
我正在编写一个应用程序,它具有一个照片数据库。每张照片都有几个与之关联的标签,并且该应用程序具有一个搜索页面,其中包含许多切换按钮,允许用户仅基于他们感兴趣的标签搜索照片。每个标签都有存储的整数ID,因为它们对应于外部数据库的ID,所以我正在尝试通过ID简单地查找它们。所有ID字段都已进行了索引。
当我编写的谓词变得非常大时,问题就出现了,因为用户可以选择从许多不同的标签进行筛选。这些标签分为3个类别[出版物、品牌和产品],因此我的查询被设置为在类别内进行“OR”操作,在这些类别之间进行“AND”操作。
一个示例查询谓词最终看起来像这样:
(parentPublication.publicationId==1 OR parentPublication.publicationId==2 OR parentPublication.publicationId==5) 
AND (ANY brands.brandId==12 OR ANY brands.brandId==2 OR ANY brands.brandId==0 OR ANY brands.brandId==3 OR ANY brands.brandId==5 OR ANY brands.brandId==6 OR ANY brands.brandId==7) 
AND (ANY products.productId==2 OR ANY products.productId==3 OR ANY products.productId==6)

他们可以变得更大,但你已经明白了要点。我的问题是,由于所有这些执行昂贵的连接,一旦用户选择超过10或15个,查询就会非常缓慢,甚至可能导致应用程序崩溃。
看起来编写如下内容会更加高效:
parentPublication.publicationId IN (1,2,5) 
AND (ANY brands.brandId IN (12,2,0,3,5,6,7))
AND (ANY products.productId IN (2,3,6))

但是我似乎无法让这种语法正常工作。

所以我的问题是:是否支持这种类型的语法,如果支持,有人能展示一下如何正确地编写它吗?

或者是否有更好的方法来处理对Core Data的这种查询呢?

1个回答

16

使用集合谓词,例如

[NSPredicate predicateWithFormat:@"parentPublication.publicationID in %@", pubIDs];
[NSPredicate predicateWithFormat:@"brands.brandID in %@", brandIDs];
[NSPredicate predicateWithFormat:@"product.productID in %@", productIDs];

现在,您只需要保留三个属性数组,并使用 andPredicateWithSubpredicates 创建一个三路复合谓词即可。

[NSCompoundPredicate andPredicateWithSubPredicates:@[
   pubPredicate, brandPredicate, productPredicate]];

应该表现良好。


谢谢@Mundi,但是每当我尝试使用那个语法时,它都会给我一个错误:无法解析格式字符串“ANY brands.brandId IN ( 12, 0, 1 )” - k.v
相同的结果:'NSInvalidArgumentException',原因:'无法解析格式字符串“ ALL brands.brandId IN ( 12, 0, 1 )”'。看起来传递给'IN'子句的数组结构不被允许或格式不正确。 - k.v
非常抱歉,我刚在谓词编程指南的这里查了一下。完全省略ANY或ALL即可。我被问题所困扰,希望你能原谅我浪费了你的时间。现在希望它可以正常工作。 - Mundi
你的数组必须是 NSNumber 对象。@[@12,@0,@1] - Mundi
可能问题就在这里,使用整数似乎有些问题,因为当我将ID转换为字符串时,它就可以正常工作了。最终,我只是按照以下格式手动构建了谓词字符串:(ANY brands.brandId IN {12,0,3,4,5,6,7,8,9,11}) AND (ANY products.productId IN {0,1,2,4,3,5,6,8}),然后它就可以正常工作了。感谢您至少让我找到了正确的方向。 - k.v
值得注意的是,现在性能非常好,因为它不必执行所有重复的连接操作。 - k.v

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接