NSPredicate using OR error - iphone

First time building an NSPredicate.
I would like to search a managedobjectcontext using this logic:
Search for a, grab all matches
Search for b, grab all matches, etc....
Nsarray *results = (has all a results, b results, etc);
My attempted predicate is:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name== %# OR name == %# OR name == %#",a,b,c];
However I get errors with this predicate...
Edited: Sample method I wrote
-(NSPredicate*)parsePartsIntoAPredicate:(NSMutableArray*)inputPartsNames{
NSSet *keys=[NSSet setWithArray:inputPartsNames];
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"any self.#name in %#", keys];
NSLog(#"predicate = %#",predicate);
return predicate;
}
Clarify: I have a database of cars (20,000) Each car has multiple parts. I want to find all cars that have part a, and all cars that have part b, and all that have part c. Then I want to return an array with cars with part a, b, c, etc...
If you think there is a better way let me know, but I am approaching this backwards. I am saying
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Cars" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[self parsePartsIntoAPredicate:inputParts]];
NSError *error;
NSArray *records = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
What am I doing wrong?

NSString *key;
NSMutableArray *tempArray;
NSPredicate *searchForName = [NSPredicate predicateWithFormat:#"name = %#", key];
NSArray *filterArray = [tempArray filteredArrayUsingPredicate:searchForName];
NSLog(#"%#",filterArray);
Where key is your searchKeyword, tempArray is your CompleteArray in which data is present.
Use Like this. Please put your data.

Use this
NSPredicate* predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"%# '%#'", #"SELF contains[c] ",searchText]];

To fetch all Cars objects that have a name which is one of the strings in the keys set or array, use
[NSPredicate predicateWithFormat:#"name IN %#", keys]

Related

Core-Data: Predicate for To-Many Relationships to get Object in many related table

In Deals Table the attributes:
ispopular(attribute)
groupname(attribute)
dealsassets(relationship-name to assets)
In Assets Table the attributes are :
assettype(attribute)
caption(attribute)
dealassetid(attribute)
assetsdeal(inverse relationshipname to deals)
Deals is Assets one to many relationship & Assets to Deals many to one relatiosnhip
I want to write a query where i need is ispopular == 1 then that related field's assets.dealasseti,
what predicate query i have to write, could some one help me out.
regards
Is this what you are looking for?
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Assets"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"assetsdeal.ispopular == 1"];
[request setPredicate:predicate];
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
Using the inverse relationship you ask for all assets where the related deal has the property "ispopular == 1".
Alternative Solution (if the first one does not work due to some StackMob restrictions):
Fetch the deals with "ispopular == 1" first:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Deals"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ispopular == 1"];
[request setPredicate:predicate];
NSError *error;
NSArray *deals = [context executeFetchRequest:request error:&error];
and use Key-Value Coding to get the related assets:
NSArray *assets = [deals valueForKeyPath:#"dealsassets.#distinctUnionOfSets.self"]

NSFetchRequest not working with predicate

I have this code:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Entry"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"version == %#", #"1.0"];
[request setPredicate:predicate];
NSArray *results = [managedObjectContext executeFetchRequest:request error:nil];
The entity "Entry" has an attribute called "version", which is a string. The predicate above doesn't seem to only be returning entries with the string as "1.0" though, returning some entries which are set to "1.1".
Am I doing this wrong?
Try putting round braces () around your predicate expression
i.e.
"(version == %#)"
have a look at the apple doc's
and try it with like in case of == or:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(version == %#)", #"1.0"];

fetching objects from core data not in a set

I'm trying to fetch objects from core data that are not in a given set, but I haven't been able to get it to work.
For instance, suppose that we have a core data entity named User, which has a few attributes such as userName, familyName, givenName, and active. Given an array of strings representing a set of usernames, we can easily fetch all the users corresponding to that list of usernames:
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User"
inManagedObjectContext:moc];
[request setEntity:entity];
NSArray *userNames = [NSArray arrayWithObjects:#"user1", #"user2", #"user3", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userName IN %#", userNames];
[request setPredicate:predicate];
NSArray *users = [moc executeFetchRequest:request error:nil];
However, I want to fetch the complement of that set, i.e., I want all the users in core data that don't have the usernames specified in the userNames array. Does anyone have an idea how to approach this issue? I thought it would be simple enough to add a "NOT" in the predicate (i.e., "userName NOT IN %#"), but Xcode throws an exception saying the predicate format could not be parsed. I also tried using the predicate builder available for fetch requests with no luck. The documentation wasn't particularly helpful either. Suggestions? Comments? Thanks for all your help :)
In order to find the objects that aren't in your array, all you have to do is something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (userName IN %#)", userNames];
That should return a request of all the objects without the ones you specified
I am not strong at core data/objective-c but the predicate should be like the following statement;
[predicateFormat appendFormat:#"not (some_field_name in {'A','B','B','C'})"];
An example:
NSMutableString * mutableStr = [[NSMutableString alloc] init];
//prepare filter statement
for (SomeEntity * e in self.someArray) {
[mutableStr appendFormat:#"'%#',", e.key];
}
//excluded objects exist
if (![mutableStr isEqual:#""])
{
//remove last comma from mutable string
mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy];
[predicateFormat appendFormat:#"not (key in {%#})", mutableStr];
}
//...
//use this predicate in NSFetchRequest
//fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat];
//...
Here's another useful example, showing how to take a list of strings, and filter out any which DON'T start with the letters A-Z:
NSArray* listOfCompanies = [NSArray arrayWithObjects:#"123 Hello", #"-30'c in Norway", #"ABC Ltd", #"British Rail", #"Daily Mail" #"Zylophones Inc.", nil];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"NOT (SELF MATCHES[c] '^[A-Za-z].*')"];
NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate];
for (NSString* oneCompany in filteredList)
NSLog(#"%#", oneCompany);
I use this kind of NSPredicate when I'm populating a UITableView with an A-Z index, and want an "everything else" section for items which don't start with a letter.

How to determine number of objects in one-to-many relationship in CoreData

So, I've got a one-to-many relationship of Companies to Employees in CoreData (using a SQLite backend on iOS, if that's relevant). I want to create a predicate that only returns Companies that have 0 Employees associated with them. I could do it by getting all the Companies and iterating over them, but that would be (I assume) much slower.
Any ideas?
Thanks,
-Aaron
After trying #falconcreek's answer and getting an error (described in my comment on his answer), I did some googling and determined that the answer was
NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees.#count == 0"];
Now everything works über efficiently. Thanks!
Assuming your Company -> Employee relationship is named "employees"
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Company" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
// the following doesn't work
// NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees = nil OR employees[SIZE] = 0"];
// use #count instead
NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees = nil OR employees.#count == 0"];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (error)
{
// Deal with error...
}

How can you reference child entity name in a predicate for a fetch request of the parent entity?

I have the need to create a complex predicate for an abstract base object. I want to have separate predicate queries for different inheriting entities and key off the sub-entity type, the example below is what I would like to do, however, I have not been able to find a way to reference the entity name or type in the predicate.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:#"MyCommonObjectBase" inManagedObjectContext:myContext];
NSPredicate *subclassAPredicate = [NSPredicate predicateWithFormat:#"someValue > %# && entityName = %#", 100, #"SubclassA"];
NSPredicate *subclassBPredicate = [NSPredicate predicateWithFormat:#"someValue < %# && entityName = %#", 50, #"SubclassB"];
request.predicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:subclassAPredicate, subclassBPredicate, nil]];
I got a response from Apple at http://bugreport.apple.com problem number 7318897:
entity.name is not a modeled property, so it's not legal. it works by accident on the binary store. The correct way to fetch subentities is to do so on the NSFetchRequest and use either setIncludesSubentities or not.
So it seems the proper solution is to have separate fetch requests and to merge the result sets after execution.
A shot in the dark here, but what about using the className value in the predicate?
NSPredicate *subclassAPredicate = [NSPredicate predicateWithFormat:#"someValue > %d AND child.className = %#", 100, #"SubclassA"];
(Notice that you had an error in your predicate format. You were using %# to try and substitute in an integer value (100). %# is only used for objects. Use %d (or some other flavor) for primitives)
EDIT Found it!
You'll want to do this:
NSPredice * p = [NSPredicate predicateWithFormat:#"entity.name = %#", #"SubclassA"];
I just tested this on one of my apps and it seems to work.
-Another edit-
Here's the test that I ran, which seemed to work:
NSManagedObjectContext * c = [self managedObjectContext];
NSFetchRequest * f = [[NSFetchRequest alloc] init];
[f setEntity:[NSEntityDescription entityForName:#"AbstractFolder" inManagedObjectContext:c]];
[f setPredicate:[NSPredicate predicateWithFormat:#"entity.name = %#", #"DefaultFolder"]];
NSError * e = nil;
NSArray * a = [c executeFetchRequest:f error:&e];
[f release];
NSLog(#"%#", a);
When I run that, a logs two NSManagedObjects, both of the #"DefaultFolder" variety (which is what I was expecting). (AbstractFolder is an abstract entity. One of the child entities that inherits from it is a DefaultFolder)
The only way of associating a predicate with an entity I know of like is this:
NSPredicate * predicate = [NSPredicate predicateWithFormat: #"(%K == %#)", fieldName, fieldValue, nil];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]];
[request setPredicate:predicate];
Maybe you were referring to the field name?
Edit: the entity is associated with the request, not with the predicate.