核心数据 - 使用数组的确切元素获取对象过滤数据

时间:2013-03-07 11:35:08

标签: objective-c core-data nspredicate one-to-many nsexpression

我有3个实体:objectobject_tagtag,我必须通过其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:

对不起,我忘了澄清一些关系。实体objecttag指向包含对象标记对的中间实体object_tag

1 个答案:

答案 0 :(得分:3)

对象实体的以下谓词应该工作:

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_tag *的多对多关系,而tag是从* object_tag *到标签的一对一关系

如果您将对象模型简化为objecttag之间的多对多关系(正如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];