I am trying to fetch an entity from coredata using NSPredicate. I am trying to do a 'search as you type' approach. It works fine on a simple product name like "chair" or "Table".
But as soon as I tried the more complicate stuff like "Wheelchair - electric - power" then when I type in "Wheelchair electric" the result is not showing. I think it has to do with my NSPredicate predicateWithFormat but I've been at this for awhile now. So I need some help.
Here is my code (these are my best guesses)
request.predicate = [NSPredicate predicateWithFormat:#" Name BEGINSWITH [c] %# ",searchText];
request.predicate = [NSPredicate predicateWithFormat:#" Name BEGINSWITH [c] %# OR Name like[cd] %# ",searchText,searchText];
Thanks in advance :)
Pondd
To have an OR search you will have to first split the search term by whitespace into an array. Then you need to create a LIKE predicate for each individual component. Finally you have to combine the individual predicates with several OR compound predicates.
Related
Some background info on my datamodel:
manufacturer <-->> item <<-->> tag
I currently generate a list of items by a fetchrequest:
- (NSFetchRequest*) rankingRequestForItem:(Item*)item {
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:#"Item"];
NSPredicate* p = [NSPredicate predicateWithFormat:#"SELF != %#",item.objectID];
r.resultType = NSDictionaryResultType;
r.resultType = NSDictionaryResultType;
r.propertiesToFetch = #[[self objectIDExpressionDescription],#"itemName",
[self rankingExpressionDescriptionForTags:[item mutableSetValueForKey:#"itemToTag"]]];
r.predicate = p;
r.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"itemName" ascending:YES]];
return r;
}
This generates a list of all items. I want to filter it for items that have a relationship to a specific manufacturer. So I'm adding a predicate after the listing of all items and it sorts by selectedManufacturer.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"itemToMa = %#", selectedManufacturer];
This works, but is grabbing a lot of items that will be filtered out. With large data sets I'm assuming will become slower and slower as it searches all items rather than just the ones associated with one manufacturer. I want to filter for items within the initial 'rankingRequestForItem' method.
Is it possible to move the above predicate with the top predicate and create a compoundpredicate?
I would not worry about performance. Core Data manages that pretty well under the hood. Sometimes the order of the predicates matters, so maybe put the manufacturer filter first.
You can combine the predicates in one as suggested in the comment to your question, or use compound predicates -- the result is pretty much the same.
I have a problem. User enters a text on a UITextField, for example: "word sentence". Now, when I filter CoreData entity I do this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title CONTAINS[cd] %# ", text];
But results returned contains entire text "word sentence", but I want do a search for every word. Is it possible with CoreData?
As written in my comment you could split the predicate with OR (through a compound predicate). For example.
[title CONTAINS[cd] %# OR title CONTAINS[cd] %#, text1, text2]
where text1 is the first term and text2 is the second. This predicate could be also created dynamically. I mean, based on text the user inserts.
If you use cd the research could be affected (perfomance will be better without it).
I have a list of users, each with
Users.accounts--->Accounts.measurements--->measurement.account
I want to pull all measurements from the measurements "table" where measurement.account=a specific account, and where measurement.type (a property) is "wind speed" as an example.
So I:
Create a fetch request on measurements
I want to create a predicate that says type="wind speed" and account={NSAccount object}
How do I do this?
Measurement type is easy:
*predicate = [NSPredicate predicateWithFormat:#"measuretype = 'air speed'];
Specifying the relationship, I don't know:
myAccountObject *myAccount=[accountFromId:#"6785"];
*accountpredicate = [NSPredicate predicateWithFormat:#"account = ???",myAccount];
In a predicate, %# is a var arg substitution for an object value, so
[NSPredicate predicateWithFormat:#"account = %#",myAccount]
is probably what you are looking for. Even for a constant string this is preferable, because it avoids problems with embedded quotation marks or other special characters, which would
have to be quoted otherwise. So your combined predicate would be:
[NSPredicate predicateWithFormat:#"measuretype = %# AND account = %#",
#"air speed", myAccount]
For more information, see "Predicate Format String Syntax" in the
"Predicate Programming Guide".
I have a Loans entity with a returnedDate attribute that can contain a date or be NIL. There is a to-many relationship with another entity, Items such that items can be related to many Loans. I would like to create a predicate where I can find all items that do not currently have a loans.returnedDate==NIL.
Assume I currently have the following:
Loan1-item1,returnedDate=NIL
Loan2-item1,returnedDate=5/4/2012
Loan3-item2,returnedDate=NIL.
I would like a predicate that returns no items.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"!(ANY loaned.returnDate==nil)"];
Returns item1.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(NONE loaned.returnDate==nil)"];
Returns item1.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(ANY loaned.returnDate!=nil)"];
Returns item1.
Can someone tell me what logic would return the appropriate results?
So I used the following predicate:
(SUBQUERY(loaned, $sub, $sub.returnDate==nil).#count == 0)
and it is returning the desired results. If you can convince me not to use SUBQUERY, please tell me how.
I have a data model which has values of type id that I was planning on casting appropriately when needed.
Is it possible for me to cast these as strings and compare them to strings from a UISearchBar using NSPredicate or do I have to use another method?
Maybe something like this:
NSPredicate * predicate;
predicate = [NSPredicate predicateWithFormat:#"CAST(%K) contains[cd] %#", employeeID , theSearchBar.text];
No. The CAST() function doesn't work that way. I think you just have to assume that the id returned from -employeeID is comparable to a string.