Существует ли NSP-предикат для фильтрации моделей с отношением один-ко-многим (фильтрация многих)? - PullRequest
2 голосов
/ 26 марта 2019

У меня есть две модели: Album и Song, альбом содержит N песен, но песня содержит только 1 альбом. Я пытаюсь создать определенный фильтр, но не смог найти NSPredicate, который дал бы мне ожидаемые результаты.

Я создал обе модели на CoreData:

Итак, я создал несколько объектов:

let song1 = Song(context: context)
song1.name = "I Love You"
song1.composer = "Ana"

let song2 = Song(context: context)
song2.name = "Hello And Goodbye"
song2.composer = "Ben"

let song3 = Song(context: context)
song3.name = "I Miss You"
song3.composer = "Marie"

let song4 = Song(context: context)
song4.name = "Lonely"
song4.composer = "Ana"

let album = Album(context: context)
album.name = "Love Songs 1"
let set = NSSet(array: [song1, song2, song3])
album.addToSong(set)

let album2 = Album(context: context)
album2.name = "Love Songs 2"
let set2 = NSSet(array: [song4])
album2.addToSong(set2)

Итак, я хотел бы сделать этот фильтр:

Получить альбомы, где Ana является композитором И имя песни содержит «n»

Я получаю модель Albums с этим предикатом:

let composerPredicate = NSPredicate(format: "ANY song.composer = %@", "Ana")
let songPredicate = NSPredicate(format: "ANY song.name contains %@", "n")

let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [composerPredicate, songPredicate])

Но по полученным результатам я получил оба альбома, но я хотел бы вернуть мне только "Love Songs 2".

Знаете, как я мог это сделать?

EDIT1: Я хотел бы найти решение, которое не использует карты, фильтры или циклы (если это возможно), потому что оно напрямую влияет на производительность, потому что я имею дело со многими данные.

1 Ответ

3 голосов
/ 26 марта 2019

Вам необходимо использовать SUBQUERY, потому что вы хотите включить альбом, только если в нем есть песня, которая соответствует обоим критериям. (Ваш составной предикат будет включать альбом, в котором одна песня соответствует первому критерию, а другая песня соответствует второму критерию).

let predicate = NSPredicate(format: "SUBQUERY(song, $S, $S.composer == %@ AND $S.name contains %@).@count > 0", “Ana”, "n")
...