核心数据 - 使用数组的确切元素获取对象过滤数据
Posted
技术标签:
【中文标题】核心数据 - 使用数组的确切元素获取对象过滤数据【英文标题】:Core Data - Get objects filtering data using the exact elements of an array 【发布时间】:2013-03-07 11:35:07 【问题描述】:我有 3 个实体:object
、object_tag
和 tag
,我必须只获取通过其 id 匹配标签数组的对象,但不仅仅是一个标签,而是完全匹配所有标签在数组中。如果数组有 3 个标签,则返回所有有这 3 个标签的对象,不多也不少。
实体如下:
object
id
name
-----
tags <--->> object_tags
object_tag
id
id_object
id_tag
-----
object <---> tags
tag <---> objects
tag
id
name
-----
objects <--->> object_tags
使用谓词和/或表达式我怎样才能得到我想要的?我尝试了很多方法,但我得到的都是包含数组中任何标签的对象,但不是一次包含所有标签。
编辑 1:
对不起,我忘了澄清一些关于人际关系的事情。实体object
和tag
指向中间实体object_tag
,其中包含对象-标签对。
【问题讨论】:
我无法理解这些关系。您能否澄清哪些关系指向哪个实体 - 或者您可以在 Xcode 中发布 Core Data 图形视图的屏幕截图。 object_tag 的用途是什么?您似乎正在定义一个可以由 Core Data 自动处理的查找表。换句话说,对象和标签可能只是 Core Data 管理的多对多关系。除非有特定原因需要 object_tag 只是将对象连接到标签之外,否则消除额外的表应该可以帮助您找到更简单的问题解决方案。 嗯,我是这么认为的。那么,您知道有/没有中间实体我该怎么做吗?感谢您的回答。 对于从对象到标签的一对多关系,这可能会有所帮助:***.com/questions/13084930/…。该解决方案也可以(可能)适应中间实体的更复杂情况。 谢谢@MartinR,但它对我不起作用。我将尝试删除中间实体,看看是否可行。如果您有其他解决方案,我会非常感谢您。 【参考方案1】:object 实体的以下谓词应该 起作用:
NSArray *tagIds = @[ @1, @4, @7 ]; // Your set of tag ids
[NSPredicate predicateWithFormat:@"(object_tags.@count == %d) AND (SUBQUERY(object_tags, $x, $x.tag.id IN %@).@count == %d)",
tagIds.count, tagIds, tagIds.count];
其中object_tags
是从 object 到 *object_tag* 的一对多关系,tag
是从 *object_tag* 到 tag 的一对一关系.
如果您将对象模型简化为 object
和 tag
之间的多对多关系(正如 David Ravetti 在评论中所建议的那样),那么谓词将如下所示:
[NSPredicate predicateWithFormat:@"(tags.@count == %d) AND (SUBQUERY(tags, $x, $x.id IN %@).@count == %d)",
tagIds.count, tagIds, tagIds.count];
如果您只想检查对象是否具有给定数组中的所有标签(但可能有更多标签),那么您可以将查询简化为
[NSPredicate predicateWithFormat:@"SUBQUERY(tags, $x, $x.id IN %@).@count == %d",
tagIds, tagIds.count];
【讨论】:
谢谢@MartinR。我删除了中间实体并建立了多对多的关系(正如 David Ravetti 所建议的那样)。您的谓词有效,但返回给我重复的对象。为什么会这样?。另一个问题,我怎样才能返回至少与数组对象匹配的对象? @ThXou:我已经更新了你第二个问题的答案。 - 我还不明白重复对象的问题。提取请求总是返回一个不同对象的数组。以上是关于核心数据 - 使用数组的确切元素获取对象过滤数据的主要内容,如果未能解决你的问题,请参考以下文章