Reputation: 1195
I have three entities like this: Publisher <-------->> Author <-------->> Book
Publisher{
id = <uniqueId>
authors -->> Author
}
Author{
id = <uniqueId>
books -->> Book //ordered relationship
publisher --> Publisher
}
Book{
info = <string_with_info>
author --> Author
}
I want to filter all books by Author id and Publisher id and get their info attribute . Something in the lines of:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"author.publisher.id == %@ AND author.id == %@", publisherId, authorId];
[request setPredicate:predicate];
[request setEntity:[NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedContext]];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch:@[@"info"]];
NSError *error = nil;
NSArray *results = [managedContext executeFetchRequest:request error:&error];
Where result should contain many strings with books infos.
I am not sure that the author.publisher.id == %@
part works.
I could get the Author and then get a MutableSet with the books entities. From where I could loop over them and push their info to a new array. This does the job but I would like to do the same with only a fetch if possible.
Edit: A solution that works is changing the predicate like so:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(0 != SUBQUERY(author, $x, (0 != SUBQUERY($x.publisher, $y, $y.id like %@).@count)).@count) AND author.id like %@ ", publisherId, authorId];
Some clarification. Author id is tied to publisher and unique only for that publisher. You could have two authors with the same id but with different publisher.
Expand upon the original question. Author books are ordered. Will the infos in results
be ordered in the same order as books are ordered in Author?. The answer per my limited test is yes.
The possible id conflict has been pointed out by Mundi and it's been noted.
Upvotes: 0
Views: 141
Reputation: 80273
First, after clarifying that your authorID is not unique, you need to use your original compound predicate:
NSPredicate(format: "author.publisher = %@ && author.authorID = %@",
publisher, authorID)
BTW, I would replace your attribute "id" with something else because there are some potential name conflicts with "id".
But you can only fetch the author, making the predicate more concise:
NSPredicate(format: "publisher = %@ && authorID = %@", publisher, authorID)
Second, books is already a set, so no need to get distinct results. Actually, you could do this without an explicit fetch if you have the author object.
author.books.map { $0.info }
is all you need. Behold how elegant Swift can be!
Upvotes: 1