I'm trying to query to find specific users based on certain credentials.
The query will only look in the User class.
First, I want the query to match the currentUser's location
Second, must match a specific category (meaning multiple users in the same location may be under the same category)
Here's what I have tried:
self.profileObj = [self.currentUser objectForKey:#"city"];
PFQuery * queryOne = [PFUser query];
[queryOne whereKey:#"city" equalTo:self.profileObj];
PFQuery * queryTwo = [PFUser query];
[queryTwo whereKey:#"category" equalTo:self.tagString];
PFQuery * query = [PFQuery orQueryWithSubqueries:#[queryOne, queryTwo]];
[query orderByAscending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:(NSArrayobjects, NSError error)
This is returning 0 results.
You don't need two separate queries since you are querying on the same User object. Also, I believe you want two AND constraints rather than OR? If so, you can just chain together two whereKeys:
PFQuery * query = [PFQuery queryWithClassName:#"User"];
[query whereKey:#"city" equalTo:self.profileObj];
[query whereKey:#"category" equalTo:self.tagString];
[query orderByAscending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
...
}];
Related
If I have pointers to multiple _User objects in an array, can i query for a value of a User.
Ex.
I have a class Groups with an array members.
members = [user1, user2, user3].
Can I do something like:
PFQuery *query = [PFQuery queryWithClassName:#"Groups"];
[query whereKey:#"members.name" isEqual:#"James"];
This can be accomplished with a nested query. Create an "innerQuery" to find Users matching the criteria. Then constrain a Group query with whereKey:matchesQuery:.
PFQuery *innerQuery = [PFUser query];
// note that referring to the "name" field only makes sense if you've
// added a name field to User (you might mean username here)...
[innerQuery whereKey:#"name" isEqual:#"James"];
// now the main query is setup to match the innerQuery
PFQuery *query = [PFQuery queryWithClassName:#"Groups"];
[query whereKey:#"members" matchesQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
}];
I am designing a database. According to documentation, when number of relationships are greater than 100 and there is extra fields, I must design a Join Table. I designed this Join Table by having two pointer value.
This pointer value is pointing to _User. Later I need only rows for currUser.
This pointer value is the objectId of another table which is an entity. My question is, how can I write a query to return objects for this table in queryfortable.
Let's say:
Table _User
Table Entity
Table Join ---> objectId Pointer1(_User) Pointer2(Event)
This look like this:
This is what I have tried so far:
First I tried in viewDidLoad to get array of invitedUser from cloud and later in queryForTable:
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query whereKey:#"objectId" containedIn:_inviteList];
but I need to access _inviteList.objectId which is not possible!
I tried to use innerQuerry or relation query. but as I just started learning parse I am not able to implement this.
PFUser *friendPointer = [PFUser currentUser];
PFQuery *query2 = [PFQuery queryWithClassName:#"Event"];
[query2 whereKey:friendPointer containedIn:_inviteList];
return query2;
This also did not work for me.
PFQuery *innerQuery = [PFQuery queryWithClassName:#"Invite"];
[innerQuery whereKey:#"invitedUser" equalTo:[PFUser currentUser]];
query = [PFQuery queryWithClassName:#"Event"];
[query whereKey:#"user" matchesQuery:innerQuery];
return query;
I appreciate if anyone can help me to write this query or re-design my table in order to have access to this query.
Pleaser try this code and give me review
PFUser *user = [PFUser currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Invite"];
[query whereKey:#"invitedUser" equalTo:user];
[query includeKey:#"invitedUser"];
[query includeKey:#"eventId"];
[query orderByDescending:#"updatedAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (error == nil)
{
for (PFObject *underobject in [objects reverseObjectEnumerator])
{
PFUser *user1 = underobject[#"invitedUser"];
NSLog(#"invitedUser is :%#",user1);
}
}
}];
I am trying to parse some objects from my data base. I'm using parse.com as web service.
The following code gives me back some object based on 4 queries, 2 of them being compound.
The variable "meetingAge" must be equal to indexAge OR "6"
The variable "meetingSex" must be equal to "sex" OR "2"
The variable "isAvaiable" must be equal to YES
The variable "author" must be different from user.username
Basically i am trying to implement a query with 2 OR conditions and 2 AND conditions.
The following code gives me a wrong result, no exceptions or stuff like that, just a wrong kind of object. I'm sure it's a syntax issue but i can't figure out how to properly write this..If i just use 1 compound query and then add the 2 AND queries to that i get a right result, but then i miss 1 filter..
PFQuery *queryAge1 = [PFQuery queryWithClassName:#"MeetingObject"];
[queryAge1 whereKey:#"meetingAge" equalTo:indexAge ];
PFQuery *queryAge2 = [PFQuery queryWithClassName:#"MeetingObject"];
[queryAge2 whereKey:#"meetingAge" equalTo:#"6"];
PFQuery *queryCompound = [PFQuery orQueryWithSubqueries:#[queryAge1,queryAge2]];
PFQuery *querySex1 = [PFQuery queryWithClassName:#"MeetingObject"];
[querySex1 whereKey:#"meetingSex" equalTo:user[#"sex"]];
PFQuery *querySex2 = [PFQuery queryWithClassName:#"MeetingObject"];
[querySex2 whereKey:#"meetingSex" equalTo:#"2"];
queryCompound = [PFQuery orQueryWithSubqueries:#[querySex1,querySex2]];
[queryCompound whereKey:#"isAvaiable" equalTo:[NSNumber numberWithBool:YES]];
[queryCompound whereKey:#"author" notEqualTo:user.username];
[queryCompound findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
}
In your line... queryCompound = [PFQuery orQueryWithSubqueries:#[querySex1,querySex2]]; you are creating a brand new query ignoring all the age stuff.
EDIT
You are overcomplicating this.
You can do this this way...
PFQuery *query = [PFQuery queryWithClassName:#"MeetingObject"];
[query whereKey:#"meetingAge" containedIn:#[#"6", indexAge]];
[query whereKey:#"meetingSex" containedIn:#[#"2", user[#"sex"]]];
[query whereKey:#"isAvaiable" equalTo:[NSNumber numberWithBool:YES]];
[query whereKey:#"author" notEqualTo:user.username];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
}
This will catch all the options you are looking for.
Also, just as a quick note. Choose your variable names to make them more readable. If they all begin with the word query it's hard to distinguish them. Also make them descriptive. queryAge1 and queryAge2 makes it harder to understand what they are doing.
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
}
}];
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.
Update
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);
}
}];
Update 2 - Let's Test
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");
}
}
}
}];
Update 3 - Predicates!
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);
}];
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;
In iOS 8.3, xcode 6.3.1
query.whereKey("name", matchesRegex:searchBar.text, modifiers:"i")
searches upper or lowercase words
I am using the backend service parse.com for a iOS app and I have a problem with querying it properly. I need help with the method whereKey:matchesKey:inQuery;
I have this code:
//NOT WORKING
PFQuery *query1 = [PFQuery queryWithClassName:#"Object"];
PFQuery *query2 = [PFQuery queryWithClassName:#"ObjectsRelations"];
[query2 whereKey:#"user" equalTo:[PFUser currentUser]];
[query1 whereKey:#"objectId" matchesKey:#"objectPointer" inQuery:query2];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// No objects
}];
It is not working the way I want. I have tried several ways for it to compare the key "objectPointer" in class "ObjectsRelations" (which is a pointer to an instance of class Object) to the actual Object in query 1. I do not get any objects back, because the comparison does not work as I want, since the key objectId is just a string and the key objectPointer is a pointer to a Object.
When I run this code, I get the intended result, but this requires me to do two api-requests to get the actual objectId as a string!
//WORKING
PFQuery *query = [PFQuery queryWithClassName:#"Object"];
PFQuery *query2 = [PFQuery queryWithClassName:#"ObjectRelations"];
[query2 whereKey:#"user" equalTo:[PFUser currentUser]];
[query2 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
PFObject *firstObject = [((PFObject*)[objects firstObject]) objectForKey:#"objectPointer"];
[query whereKey:#"objectId" equalTo:firstObject.objectId];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//Getting the objects correctly from the class Object!
}];
}];
How to do this with a single api-request? How to compare a instance of a Class to a pointer of a class with a query?
Something like this is what i want to do: (Pseudo Code)
[query1 where:SELF matches:#"objectPointer" inQuery:query2];
Any suggestions?
I just searched this exact same problem and there are a number of questions on the Parse forum regarding it:
Trouble with nested query using object_id
Assistance with relational query
Compare string to pointer in query with does not match key in query
The first one explains a hack to include an extra field (in this case) in your ObjectRelations class. This key/field would be a string that would be the objectId of the pointer. It would be in addition to the key/field that holds the pointer.
If you look through the questions you can see that as of now there doesn't seem to be an answer directly from Parse regarding this.
Instead of adding an additional column with type String to contain the objectID it points to, I would suggest to add a column on each object with type Pointer to point to the object itself. This would dramatically reduce the amount of the columns you have to add. The only downside is this must be done on Cloud Code.
At this question's scenario, you'll have two queries like:
//Inner query
//Library containing pointer<Deck> & pointer<User>
PFQuery * subscriptions = [PFQuery queryWithClassName:#"subscription"];
[subscriptions whereKey:#"User" equalTo:[PFUser currentUser]];
//Outer query
//Pull down a list of deckStore objects not included in the subscriptions for current user
PFQuery * decks = [PFQuery queryWithClassName:#"deckStore"];
Then instead of:
[decks whereKey:#"objectId" doesNotMatchKey:#"deckString" inQuery:subscriptions];
You can do this:
[decks whereKey:#"this" doesNotMatchKey:#"deck" inQuery:subscriptions];
Here's a sample of what the Cloud Code should be added:
Parse.Cloud.afterSave("Deck", function(request) {
var deck = request.object;
// To make sure this is the first time of "afterSave" of this object.
if (deck.createdAt.getTime() == deck.updatedAt.getTime()) {
// "this" is the column which contains the pointer of the object itself.
if (deck.get("this") == null) {
deck.set("this", deck);
deck.save();
}
}
}
I have the same problem. This is my solution:
PFQuery *query1 = [PFQuery queryWithClassName:#"tableClass"];
[query1 whereKey:#"objectId" equalTo:[(PFObject *)[object objectForKey:#"pointerField"] objectId]];
PFObject *obj1 = [query1 getObjectWithId:[(PFObject *)[object objectForKey:#"pointerField"] objectId]];
NSString *pointerName = [obj1 objectForKey:#"name"];