I have a core data DB with multiple entities. There is a parent entity called "Person" which has many "Friends", "Friends" have many "Activities", and "Activities" have "Types" ("Types has a to-many relationship to "Activities"). What I'm trying to achieve is filtering all the "Person" entities by "Types". A user would be tapping on a "Type" and then I would refresh my table and filter the "Person" entities that are displayed by the "Types" that are associated with them.
Currently I'm thinking I have to use a compound predicate but I'm completely sure how to go about it. So far all I've done is printed out the values I've wanted by looping through my fetchedObjects like so:
NSArray *persons = self.fetchedResultsController.fetchedObjects;
for (JIPerson *person in persons) {
JIFriend *friend = person.friends.anyObject;
JIActivity *activity = friend.activities.anyObject;
JIType *type = activity.type;
NSLog(#"%#", type.name);
}
This prints out the values correctly, but I need to filter my table using these values. How can I achieve that?
Seems like I got it. Using NSPredicate you can traverse a deep relationship like this using dot notation. My implementation went as follows:
- (void)filterPersonByType:(NSString *)typeName {
NSPredicate *typePredicate = [NSPredicate predicateWithFormat:#"ANY friends.activities.type.name CONTAINS[cd]%#", typeName];
}
Yes, you can use dot notation with NSPredicate. You might want to have the type be an actual type, though, that would be cleaner than just doing string comparisons.
Related
As part of an autocomplete box, I am searching names within an array of contacts. However, after the user picks a name from the suggested List, I need to grab the id of the contact which is in the array of contact objects but not the array of names that appear in the suggest box. I've been working with just the names as that's what I want to display in the suggestion box but have an array of contacts as well.
How would I convert code below (probably using key values) to search the name dimensions of an array of objects instead of an array of names so as to keep track of the ids of the objects. I am kind of fuzzy on arrays and key values.
//the array being searched looks something like #[#"John", #"Dave", #"Sam", #"Xian", #"Ahmed", #"Johann"];
//I want to search the names in an array that looks something like:
(
{
first = "John";cid = 2;},
{
first = "Dave";cid = 44;},
{
first = "Xian";cid=99})
//this code works great to search names but I lose track ids. Thank you for any suggestions.
-(void)searchArray: (NSMutableArray*) array forString: (NSString *) term {
[_contactsSuggested removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",term];
NSArray *tempArray = [array filteredArrayUsingPredicate:predicate];
_contactsSuggested = [NSMutableArray arrayWithArray:tempArray];
[_autocompleteTableView reloadData];
}
Create a Contact object. Give it a name property, an id property, and any other properties you need. Then write code that searches an array of Contact objects rather than just an array of names. You could then create a predicate using predicateWithBlock to filter the items that match your name property.
I have a realm database filled with Restaurant objects that have a url parameter. I'd like to fetch the objects where the url contains what the user has typed in a UITextField.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"url CONTAINS '%#'", self.searchQuery];
RLMResults<Database *> *results = [Database objectsWithPredicate:pred];
if ([results count] == 0) {
NSLog(#"results count == 0");
return nil;
}
Now, when I run this, I always get 0 results. Eventhough I have two example entries that have 'http://www.testingthis.com' as an url and the search query is 'testingthis'. Any ideas as to why I'm not getting results?
You need to perform your search query against the Restaurant class itself; not Database. Realm uses the class you specify to determine which table in which to apply the query.
As an aside, you can also inline NSPredicate queries with +[RLMObject objectsWhere:], so it's not necessary to create a separate NSPredicate object (unless you've got a specific reason). :)
RLMResults *restaurants = [Restaurant objectsWhere:#"url CONTAINS '%#'", #"testingthis"];
If you're trying to query for Restaurant objects that aren't in the default Realm, then you can alternatively use +[RLMObject objectsInRealm: where:] to explicitly control which database you're querying.
I am using Realm database for iOS application where i have a use case in which i want to filter result set by distinct values for a particular field. This field is not a primary key of the realm table.
I was not able to construct query for that.
Sample query :
RLMResults *allFiles = [FileRLMObject objectsInRealm:realmObject where:#"colA == %#", #"test1"];
FileRLMObject is a subclass of RLMObject from realm library
here table contains one column with name colB. While getting allFiles results, i want to get rows which are having distinct colB values.
Any suggestions how i can achieve this?
Realm doesn't support distinct queries yet. You can subscribe issue #1103 to track progress on that.
As a workaround, you could query for all values for colB first and then select objects for each value of it, as seen below:
NSArray *values = [FileRLMObject.allObjects valueForKey:"type"];
NSSet *distinctValues = [NSSet setWithArray:values];
NSMutableArray *allFiles = [NSMutableArray new];
for (NSString *colB in distinctValues) {
// This takes the firstObject.
// You might want to modify the sort order to make sure
// you get a certain object in case that there may exist
// multiple objects per distinct value.
FileRLMObject *object = [FileRLMObject objectsWhere:#"colB == ?", colB].firstObject;
[allFiles appendObject:object];
}
I have two Entities, Student and Course, where each has a to-many relationship to the other (i.e., a Student has 0 or more Courses, and a Course has 0 or more Students).
I need to obtain all Students who are enrolled in a Course. I also need to obtain all Courses in which a given Student is enrolled (by firstName).
An pseudo-predicate would be: all students who have a course whose name is equal to courseName.
So my question consists of two parts:
What is a valid NSPredicate for obtaining all students with a certain course name?
What is a valid NSPredicate for obtaining all courses where a student with a certain firstName is enrolled.
For your reference, here are my entities:
1) Use this to filter an array of students that are in a specific course with courseName :
[NSPredicate predicateWithFormat:#"ANY courses.name like %#", courseName]
Alternatively, if you already have a course object (and name is unique in call course objects), you can simply get all of its students by accessing its students property, i.e.
course.students // returns an NSSet/NSOrderedSet based on your model setup
2) Use this to filter an array of courses that have a student with a certain firstName :
[NSPredicate predicateWithFormat:#"ANY students.firstName like %#", firstName]
Note: NSSet and NSOrderedSet have a method array to get an array of the objects.
See also the docs on NSPredicate under Using Predicates with Key-Paths.
What is a valid NSPredicate for obtaining all students with a certain course name?
[NSPredicate predicateWithFormat:#"name= %#", courseName];
Use above predicate to fetch particular course while has name = courseName;Set that predicate on "Course" entity not "Student" entity.
AFter executing above fetch request, you will have array of courses having that courseName.
Course *course = [fetchedResults objectAtIndex:0];
Now to get all students in that course,
NSArray *students =[course.students allObjects];
now students is an array of "Student" entity objects.
Similarly ,
What is a valid NSPredicate for obtaining all courses where a student with a certain firstName is enrolled.
[NSPredicate predicateWithFormat:#"firstName = %#", name];
Use above predicate to fetch particular student who has name = firstName;Set that predicate on "Student" entity.
AFter executing above fetch request, you will have array of students having that firstName.
Student *student = [fetchedResults objectAtIndex:0];
Now to get all courses for that student,
NSArray *courses =[student.courses allObjects];
now courses is an array of "Course" entity objects.
Hope this helps.
Suppose two entities: EntityA and EntityB, connected by many to many relationship. Suppose the relation attributes are relatedEntityBs and relatedEntityAs respectively. And I have an NSArray of EntityB instances. I want to find all EntityA instances which have in relation all instances that are in nsarray. That is if the array is [entityB1,.....,entityBn]. Find all EntityA instances, which are related with entityB1,wntityB2 till entityBn. How can I write this kind of predicate?
This predicate should do it:
NSMutablArray *predicateArray = [NSMutableArray array];
for (int i=0;i<entityBArray.count;i++){
NSPredicate *subPredicate = [NSPredicate predicateWithFormat:#"ANY relatedEntityBs contains %#",[entityBArray objectAtIndex:i];
[predicateArray addObject:subPredicate] ;
}
NSCompoundPredicate *daddyPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
Basically each sub predicate checks if relatedEntityB contains a single object of the array and finally the daddyPredicate combines them all in with OR.