iOS Core Data complex predicate.
iOS Core Data complex predicate.
- Subject: iOS Core Data complex predicate.
- From: Sandro Noël <email@hidden>
- Date: Thu, 17 Mar 2011 15:15:43 -0400
Greetings!
I am facing a problem with a complicated predicate I'm building.
it keeps returning multiple instances of the same records.
if every predicate used alone works as a charm, problems occur when they are combined together.
my model is constructed as so
------------------------------------
Table 1 contains most descriptive fields.
name
description
additional information.
Table 2 contains the categories
name for the category
keyword
Table 3 contains elements
name of the element
keyword
table 1 has a to-many relationship to table 2
table 2 has a to many inverse relationship to table 1
table 1 has a to-many relationship to table 3
table 3 has a to many inverse relationship to table 1
-one item from table 1 can belong to many categories and one category can be assigned to multiple items from table 1
-one item from table 1 can have many elements, and one element can belong to many items of table 1;
----------------------------
My search criteria's are as so.
user can enter keywords to search the tiems.
user can select from a list of categories the categories to search for.
user can select fro ma list of elements the elements to include in the search.
The keywords are separated in components and filtered against a StopWord array as to keep only the relevant words to build the predicate.
each keyword is OR'd against three search field.
and then AND together as to assure all keywords appear in one particular item of table 1
if ([self.searchText.text length] > 0){
NSArray * components = [self.searchText.text componentsSeparatedByString:@" "];
for (NSString *component in components){
if (!isInFrenchStopWords(component)){
NSMutableArray *orSubPredicates = [NSMutableArray new];
[orSubPredicates addObject:[NSPredicate predicateWithFormat:@"%@ IN[cd] self.name",component]];
[orSubPredicates addObject:[NSPredicate predicateWithFormat:@"%@ IN[cd] self.description",component]];
[orSubPredicates addObject:[NSPredicate predicateWithFormat:@"%@ IN[cd] self.addInfo",component]];
// build a OR Predicate for this particular keyword.
[keywordsSubPredicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:orSubPredicates]];
[orSubPredicates release];
}
}
// keywords are combined in a AND predicate, all keywords must have a hit.
[finalSubPredicates addObject:[NSCompoundPredicate andPredicateWithSubpredicates:keywordsSubPredicates]];
}
Then if there are selected categories these are also predicated as so.
the selected categories ManagedObject are stored in an NSDictionary
A predicate is built for every selected category, because it is a many to many relationship.
i've tried using category.name but that did not work.
if ([self.categoryPredicateDict count]){
NSArray * components = [self.categoryPredicateDict allValues];
for (ModelCategory *component in components){
[categoriesSubPredicates addObject:[NSPredicate predicateWithFormat:@"%@ IN[cd] categories",component]];
}
// or any selected Category
[finalSubPredicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:categoriesSubPredicates]];
}
A predicate is built for every selected element, because it is a many to many relationship.
if ([self.elementPredicateDict count]){
NSArray * components = [self.elementPredicateDict allValues];
for (ModelElement *component in components){
[elementSubPredicates addObject:[NSPredicate predicateWithFormat:@"%@ IN[cd] elements",component]];
}
// or any selected elements
[finalSubPredicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:elementsSubPredicates]];
}
and then to finalize everything and put it all together.
return [NSCompoundPredicate andPredicateWithSubpredicates:finalSubPredicates];
then this predicate is fed to a fetch Request which in turn is fed to a fetched Result Controller.
the fetch is configured to [fetchRequest setReturnsDistinctResults:YES];
The problem as stated in the introduction this complete predicate returns multiple instances of the same record and it should not.
if any of you see a flaw in the logic or anything, please comment, I'm currently so deep into it, I cant see it anymore. :)
I hope I have not missed nay details.
Thank you!!!
Sandro.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden