Reputation: 7639
I'm needing to use the parse.com method orQueryWithSubquerries:
to create a combined conditional query.
Here is my code for it:
PFQuery *testQuery = [PFUser query];
[testQuery whereKey:@"displayName notEqualTo:@"Bob"];
PFQuery *testQuery2 = [PFUser query];
[testQuery whereKey:@"username" notEqualTo:@"frank"];
PFQuery *orQuery = [PFQuery orQueryWithSubqueries:@[testQuery, testQuery2]];
[orQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
if (!error) {
PFUser *user = [users firstObject];
}
}];
The code runs fine, but it returns all of my user objects, including the ones that should be filtered out from the 2 queries. Am I using this method wrong, or is there a certain way that I need to use it?
Edit:
I have also attempted to use this method exactly like how this parse.com example does, but it still doesn't work properly.
PFQuery *testQuery = [PFUser query];
[testQuery whereKey:@"numberOfPhotos" greaterThan:@(3)];
PFQuery *testQuery2 = [PFUser query];
[testQuery whereKey:@"numberOfPhotos" lessThan:@(1)];
PFQuery *orQuery = [PFQuery orQueryWithSubqueries:@[testQuery, testQuery2]];
[orQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
if (!error) {
// users still contains every user in the app even though it shouldn't according to the parse example
}
}];
Upvotes: 1
Views: 432
Reputation: 1
In iOS 8.3, xcode 6.3.1
query.whereKey("name", matchesRegex:searchBar.text, modifiers:"i")
searches upper or lowercase words
Upvotes: 0
Reputation: 7639
After looking into this once again I ended up changed my solution to being regex based rather than predicate. For my purposes that means I don't need to create an additional lowercase display name property since Parse regex allows for case-insensitive options. Also I can more easily change the parameters of the search with higher levels of flexibility.
My code now looks like this:
// Uses regex to remove white space at the beginning and end of search text
NSString *modifiedSearchText = [Utility stringTrimmedForLeadingAndTrailingWhiteSpacesFromString:self.searchText];
PFQuery *userUsernameQuery = [PFUser query];
// the @"i" modifier is stated in the parse documentation and means case-insensitive
[userUsernameQuery whereKey:@"username" matchesRegex:modifiedSearchText modifiers:@"i"];
PFQuery *userDisplaynameQuery = [PFUser query];
[userDisplaynameQuery whereKey:@"displayName" matchesRegex:modifiedSearchText modifiers:@"i"];
PFQuery *userQuery = [PFQuery orQueryWithSubqueries:@[userUsernameQuery, userDisplaynameQuery]];
[userQuery orderByAscending:@"username"];
return userQuery;
Upvotes: 0
Reputation: 53112
You don't need to do a compound query, just query regularly:
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:@"displayName" notEqualTo:@"Bob"];
[userQuery whereKey:@"username" notEqualTo:@"frank"];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
if (!error) {
PFUser *user = [users firstObject];
}
}];
You're confusing the use of a compound query, as you have it currently,
TestQuery = All users whose display isn't bob. (includes users whose username is frank)
TestQuery2 = All users whose username isn't frank. (includes users whose display name is Bob)
When you combine them, you get all of the users, your compound is contradictory.
Basically, all of the users left out in query1 are included in query2. And, all the users left out in query2 are included in query1. When you combine these queries, they fill in the missing space and you get all users.
If you're trying to do hasPrefix, it seems like it should work fine:
NSString * prefixToSearch = ...;
PFQuery * displayNameQuery = [PFUser query];
[displayNameQuery whereKey:@"displayName" hasPrefix:prefixToSearch];
PFQuery * usernameQuery = [PFUser query];
[usernameQuery whereKey:@"username" hasPrefix:prefixToSearch];
PFQuery * compoundQuery = [PFQuery orQueryWithSubqueries:@[displayNameQuery, usernameQuery]];
[orQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
if (!error) {
NSLog(@"Found %i users", users.count);
}
}];
PFQuery *testQuery = [PFUser query];
[testQuery whereKey:@"numberOfPhotos" greaterThan:@(3)];
PFQuery *testQuery2 = [PFUser query];
[testQuery whereKey:@"numberOfPhotos" lessThan:@(1)];
PFQuery *orQuery = [PFQuery orQueryWithSubqueries:@[testQuery, testQuery2]];
[orQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
if (!error) {
// users still contains every user in the app even though it shouldn't according to the parse example
for (PFUser * user in users) {
int numberOfPhotos = [user[@"numberOfPhotos"] intValue];
if (1 <= numberOfPhotos && numberOfPhotos <= 3) {
NSLog(@"Query is failing");
}
}
}
}];
Via our conversation, we got it working with this:
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"keyOne BEGINSWITH 'z' OR keyTwo BEGINSWITH 'a'"];
PFQuery * userQuery = [PFQuery queryWithClassName:@"_User" predicate:predicate];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSLog(@"Found objects: %@", objects);
}];
Upvotes: 2