Filter CoreData entity with array of strings - search

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).

Related

Is a subquery needed for my nspredicate to work properly?

I have an array of custom objects that have beds (1,2,3), fireplace (yes or no), den (yes or no) and ceiling heights (9-11,11-14,14-16). I need to allow filtering based on any/all/none of the items being selected to filter by. So a user may want to see 1 & 2 beds, den, fireplace and 9-11 foot ceilings. Or just 1 & 2 beds. My current predicate works for some of these. But it doesn't match all - only some. I am thinking I need a subquery. How to create a nested(?) subquery based on an array of filters?
Right now, the user selects buttons and those are matched against Filters and I use those to create my predicate.
Current predicate
Filters is an array of keys and predicate strings like 'beds, 1' and 'ceilings, 9-11'
`NSMutableArray *subPredicates = [NSMutableArray array];
for (Filter*fil in filters) {
NSPredicate *unitsPredicate = [NSPredicate predicateWithFormat:#"%K == %#", fil.key, fil.predicate];
[subPredicates addObject:bedsPredicate];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
NSLog(#"homes: %#", [searchArray filteredArrayUsingPredicate:predicate]);
NSArray *ar = [searchArray filteredArrayUsingPredicate:predicate];
I'd like to allow someone to pick any of the criteria and return appropriate data.
Subqueries are used with to-many relationships. If you want to filter multiple values then the class of fil.predicate should be an array (or set) of values. The predicate format is %K IN %#, for example
for (Filter*fil in filters) {
NSPredicate *unitsPredicate;
if ([fil.predicate isKindOfClass:[NSArray class]])
unitsPredicate = [NSPredicate predicateWithFormat:#"%K IN %#", fil.key, fil.predicate];
else
unitsPredicate = [NSPredicate predicateWithFormat:#"%K == %#", fil.key, fil.predicate];
[subPredicates addObject:bedsPredicate];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
See Aggregate Operations in Predicate Programming Guide.

Coredata fetch request using NSPredicate

I want to do a phone number search in sqlite db. Phone table have a number field which holds a string value (eg: +1 (2-34)56-78 ).
If user enters search text as "234", then I need to fetch the phone numbers with only digits(eliminating all other alphabets or special characters in the string stored) using NSPredicate and compare it with the entered string. Should I do this using a predicate in a fetch request?
I tried with following predicate and it doesn't return me the expected result:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"contactName != null AND SUBQUERY(phoneList, $phone, ANY $phone.number CONTAINS[c] %#).#count > 0",searchText];
IS there any way to get this done? Can I use regular expression with NSPredicate for this?
NSPredicate doesn't support that kind of matching. Your Core Data model should include data that your app requires for filtering-- which might mean extra fields that are not normally visible to users. If you need to match numbers without regard to non-numeric characters, you should add a field which contains that data. If the actual string is +1 (2-34)56-78, add a secondary field where you store 12345678. Use this extra field in the predicate.

How do I filter CoreData results based on a relationship

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".

Creating Core Data predicate to get data within one-to-many relationship

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.

having problem with NSPredicate predicateWithFormat "OR"

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.

Resources