Базовые данные - Получить объекты, фильтрующие данные, используя точные элементы массива
У меня есть 3 лица: object
, object_tag
а также tag
и мне нужно получить только объекты, соответствующие массиву тегов по его идентификатору, но не просто тегу, а точно совпадающему со всеми тегами в массиве. Если массив имеет 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
, который содержит пары объект-тег.
1 ответ
Следующий предикат для объекта объекта должен работать:
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 * к тегу.
Если вы упростите вашу объектную модель до отношения многих ко многим между object
а также tag
(как предложил Дэвид Раветти в комментарии), тогда предикат будет выглядеть так:
[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];