I have 3 entities: object
, object_tag
and tag
, and i have to get just the objects matching an array of tags by its id, but not just a tag, but that exactly matches all the tags in the array. If the array has 3 tags, return all the objects that have these 3 tags and not more neither less.
The entities are like:
object
{
id
name
-----
tags <--->> object_tags
}
object_tag
{
id
id_object
id_tag
-----
object <---> tags
tag <---> objects
}
tag
{
id
name
-----
objects <--->> object_tags
}
Using predicates and/or expressions how can i get what i want?. I've tried many ways, but all I've gotten have been objects that include any of the tags in the array, but not all the tags at once.
EDIT 1:
Sorry, i forgot to clarify something about relationships. The entities object
and tag
points to the intermediate entity object_tag
, that contains object-tag pairs.
The following predicate for the object entity should work:
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];
where object_tags
is the to-many relationship from object to *object_tag*, and tag
is the to-one relationship from *object_tag* to tag.
If you simplify your object model to a many-to-many relationship between object
and tag
(as suggested by David Ravetti in a comment), then the predicate would look like this:
[NSPredicate predicateWithFormat:@"(tags.@count == %d) AND (SUBQUERY(tags, $x, $x.id IN %@).@count == %d)",
tagIds.count, tagIds, tagIds.count];
If you only want to check that the object has all tags from the given array (but might have more tags), then you can simplify the query to
[NSPredicate predicateWithFormat:@"SUBQUERY(tags, $x, $x.id IN %@).@count == %d",
tagIds, tagIds.count];