Reputation: 5789
I have an NSPredicate
which includes multiple aggregate filters, which is throwing an exception.
I have the following core data model:
I want to pick those ApparelItems
for which any of the colours
has an rgb
of 13576743, and for which all of the picks
have a pickTime
earlier than a given NSDate
.
My code to create the predicate is:
let request = NSFetchRequest(entityName: "ApparelItem")
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "ANY colours.rgb = 13576743"))
// find the NSDate representing midnight x days ago
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: [])
{
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "(ALL picks.pickTime < %@)", midnightXDaysAgo))
}
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
let searchData = try? objectContext.executeFetchRequest(request)
I get the following exception:
Exception name=NSInvalidArgumentException, reason=Unsupported predicate (ANY colours.rgb == 13576743) AND ALL picks.pickTime < CAST(479347200.000000, "NSDate")
I have tried:
Each individual predicate works fine. Ie ANY colours.rgb = ...
works, also ALL picks.pickTime < ...
works. They just don't work when combined into the same query.
Combining the two using into a single query, linked with AND
, rather than using NSCompoundPredicate
. Result is the same.
Is it possible that core data simply doesn't support filtering on more than one to-many relationship? That would seem odd. In which case how should I do the above?
Upvotes: 6
Views: 1498
Reputation: 80265
Colors and picks are two different entities, so you should be able to filter by both without using SUBQUERY
. One predicate or a compound predicate should both be fine.
From the error message it seems that perhaps something is wrong with the date. Please check you have the expected data type in your managed object subclasses. If you used "primitive values" when creating the subclasses, you will need NSTimeInterval
rather than NSDate
.
Upvotes: 0
Reputation: 1734
Probably could try SUBQUERY()
for NSPredicate
.
The code below I came out from some guess and not very sure if it works or not. Usually it takes me trial and error many times for a to-many query clause with NSPredicate
.
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "SUBQUERY(colours, $colour, ANY $colour.rgb = 13576743).@count > 0"))
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: []) {
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "SUBQUERY(picks, $pick, ALL $pick.pickTime < %@).@count > 0", midnightXDaysAgo))
}
Upvotes: 2