I would like to make a search feature that queries two different key from the same class. What kind of regular expression could I use that return the most accurate values. Example:
- (void)searchTableList {
[self.results removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName:#"TC"];
CLLocationCoordinate2D coordinate = [self.delegate.location coordinate];
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:coordinate.latitude
longitude:coordinate.longitude];
PFQuery *query1 = [PFQuery queryWithClassName:#"TC"];
[query1 setLimit:1000];
[query1 whereKey:#"location"
nearGeoPoint:geoPoint
withinKilometers:5];
[query1 whereKey:#"courses" matchesRegex:[NSString stringWithFormat:#"%#",[self.searchBar.text lowercaseString]]];
[query1 whereKey:#"owner" notEqualTo:[PFUser currentUser].username];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for( PFObject * object in objects)
{
[self.results addObject:object];
}
[query setLimit:1000];
[query whereKey:#"location"
nearGeoPoint:geoPoint
withinKilometers:5];
[query whereKey:#"owner" matchesRegex:[NSString stringWithFormat:#"%#",[self.searchBar.text lowercaseString]]];
[query whereKey:#"owner" notEqualTo:[PFUser currentUser].username];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for( PFObject * object in objects)
{
[self.results addObject:object];
}
[self.tableView reloadData];
}];
}];
}
How could I take these two queries and order them in such a way that the most accurate information has priority.
If you want to find objects that match one of several queries, you can use orQueryWithSubqueries: method. For instance, if you want to find players with either have a lot of wins or a few wins, you can do:
PFQuery *lotsOfWins = [PFQuery queryWithClassName:#"Player"];
[lotsOfWins whereKey:#"wins" greaterThan:#150];
PFQuery *fewWins = [PFQuery queryWithClassName:#"Player"];
[fewWins whereKey:#"wins" lessThan:#5];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[fewWins,lotsOfWins]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains players with lots of wins or only a few wins.
}];
Related
Currently, I am querying the database twice to achieve a list of all users nearby who are not already being followed by the current user. Here is my nested query:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
[followingActivitiesQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *followedUserIds = [[NSMutableArray alloc] init];
// Obtain an array of object ids for all users being followed
for (PFObject *object in objects) {
PFUser *followedUser = [object objectForKey:kFTActivityToUserKey];
[followedUserIds addObject:followedUser.objectId];
}
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notContainedIn:followedUserIds];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];
}
}];
My question is, is this a viable solution? I feel guilty about having to query the server twice in order to achieve this, but I was not able to do it all in one query. I could not compare a parse pointer from the ActivityClass to the Users class, since the Users class is the class being pointed to, and because of this I couldn't think of a way to do it all in one query.
You're in luck - this can be done in a single query using the whereKey:doesNotMatchKey:inQuery: method of PFQuery.
Parse will treat this as a single, compound query against the database. Totally guilt-free :)
Try this instead:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
//The next line is your new compound query
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey doesNotMatchKey:#"objectId" inQuery:followingActivitiesQuery];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];
I was trying this
PFQuery *allDealsQuery = [Deal query];
PFRelation *favoritedDealsRelation = [user objectForKey:#"favoritedDeals"];
PFQuery *favoritedDealsQuery = [favoritedDealsRelation query];
PFRelation *redeemedDealsRelation = [user objectForKey:#"redeemedDeals"];
PFQuery *redeemedDealsQuery = [redeemedDealsRelation query];
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:favoritedDealsQuery];
//Parse does not support more than 2 where queries???
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:redeemedDealsQuery];
[allDealsQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
onSuccess(objects);
}
else {
onError(error);
}
}];
When I tried to use two queries, the answer was different from what was expected.
So should I use be using only one doesNotMatchKey query?
Try referencing parse documentation on Compound Queries:
https://parse.com/docs/ios_guide#queries-compound/iOS
Compound Queries
If you want to find objects that match one of several queries, you can use orQueryWithSubqueries: method. For instance, if you want to find players with either have a lot of wins or a few wins, you can do:
PFQuery *lotsOfWins = [PFQuery queryWithClassName:#"Player"];
[lotsOfWins whereKey:#"wins" greaterThan:#150];
PFQuery *fewWins = [PFQuery queryWithClassName:#"Player"];
[fewWins whereKey:#"wins" lessThan:#5];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[fewWins,lotsOfWins]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains players with lots of wins or only a few wins.
}];
I am trying to print the name of a category using Parse in iOS and Objectve-C. Thanks for looking. Let me know if you have any questions.
CategoryInBudget Table
category(pointer)
amount(number)
user(pointer)
Category Table
name(string)
Here is my code:
PFQuery *query = [PFQuery queryWithClassName:#"CategoryInBudget"];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
[query includeKey:#"Category"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (PFObject *object in objects) {
NSLog(#"%#", object[#"Category"][#"name"];
}
}];
I want to use as the backend of my app Parse, and suppose that I have a class with different restaurants, menus for each restaurant and for each menu different products, I have a class Place, Menu, Product and MenuItems:
The MenuItem class has:
Pointe menu
Pointer product
The Menu class:
Pointer place
Once chosen restaurant have to show all products for that restaurant:
My Code:
PFQuery *query = [PFQuery queryWithClassName:#"Places"];
[query whereKey:#"name" equalTo:PlaceSelect];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
PFObject *Menu;
if (!error)
{
for (PFObject *ob in objects)
{
Menu = ob;
}
}
PFQuery *query1 = [PFQuery queryWithClassName:#"Menus"];
[query1 whereKey:#"place" equalTo:Menu];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects2, NSError *error2) {
PFObject *MenuItems;
if (!error2)
{
for (PFObject *ob2 in objects2)
{
MenuItems = ob2;
}
}
PFQuery *query2 = [PFQuery queryWithClassName:#"MenuItems"];
[query2 whereKey:#"menu" equalTo:MenuItems];
[query2 selectKeys:#[#"product"]];
[query2 findObjectsInBackgroundWithBlock:^(NSArray *objects3, NSError *error3) {
PFObject *Products;
if (!error3)
{
for (PFObject *ob3 in objects3)
{
Products = ob3;
NSLog(#" %# ",Products);
}
I get related products but when I want to filter by type: drinks, starters, etc... It gives me all the products of all places them...
PFQuery *retrievedDrink = [PFQuery queryWithClassName:#"Products"];
[retrievedDrink whereKey:#"type" equalTo:#"drink"];
[retrievedDrink whereKey:#"objectId" equalTo:Products.objectId];
[retrievedDrink findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
DrinksArray = [[NSArray alloc] initWithArray:objects];
NSLog(#"numero de productos Drinks= %i ",[DrinksArray count]);
}];
Thanks in advance, if anyone knows a way to more efficiently please I would like to clarify my doubts
Get rid of this line
[retrievedDrink whereKey:#"objectId" equalTo:Products.objectId];
That is returning all your objects.
You have a duplicate array of your objects that is not needed, and also, do an error check.
This should find all the drinks stored in your Parse class, store them in an array called objects and allow you to query that array in your findObjectsInBackgroundWithBlock
PFQuery *retrievedDrink = [PFQuery queryWithClassName:#"Products"];
[retrievedDrink whereKey:#"type" equalTo:#"drink"];
[retrievedDrink findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"numero de productos Drinks= %i ",[objects count]);
}
}];
Hello to everyone in the query I posted I'm trying to retrieve all of the posts and PfUserCurrent all posts of people who have shared a friendship with PfUserCurrent.
The query works fine but I have only one problem, the query shows me all the posts of Friends of the CurrentUser but does not show me those sent by the CurrentUser ... I've tried several attempts but I could not fix this ... Can you explain where I'm wrong?
-(void)QueryForPost {
PFQuery *QueryForFriend=[PFQuery queryWithClassName:#"Friendships"];
[QueryForFriend whereKey:#"To_User" equalTo:[PFUser currentUser]];
[QueryForFriend whereKey:#"STATUS" equalTo:#"Confirmed"];
PFQuery *QueryYES = [PFQuery queryWithClassName:#"Post"];
[QueryYES whereKey:#"FLASH_POST" equalTo:[NSNumber numberWithBool:YES]];
[QueryYES whereKey:#"UserSelected" equalTo:[PFUser currentUser]];
PFQuery *QueryNO = [PFQuery queryWithClassName:#"Post"];
[QueryNO whereKey:#"FLASH_POST" equalTo:[NSNumber numberWithBool:NO]];
[QueryNO whereKey:#"Author" matchesKey:#"From_User" inQuery:QueryForFriend];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[QueryYES,QueryNO]];
[query includeKey:#"Author"];
[query orderByDescending:FF_CREATEDAT];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
if (!error) {
NSLog(#"%#", results);
ArrayforPost = [[NSMutableArray alloc] init];
for (PFObject *object in results) {
[ArrayforPost addObject:object];
}
[self.FFTableView reloadData];
}
}];
}
After a long discussion with #rory, here we come to the correct answer:
-(void)QueryForPost {
PFQuery *QueryForFriend=[PFQuery queryWithClassName:#"Amicizie"];
[QueryForFriend whereKey:#"A_User" equalTo:[PFUser currentUser]];
[QueryForFriend whereKey:#"STATO" equalTo:#"Confermato"];
[QueryForFriend includeKey:#"Da_User"];
PFQuery *QueryYES = [PFQuery queryWithClassName:#"Post"];
[QueryYES whereKey:#"FLASH_POST" equalTo:[NSNumber numberWithBool:YES]];
[QueryYES whereKey:#"Scelti" equalTo:[PFUser currentUser]];
PFQuery *normalPostByFriends = [PFQuery queryWithClassName: #"Post"];
[normalPostByFriends whereKey: #"FLASH_POST" equalTo: [NSNumber numberWithBool: NO]];
[normalPostByFriends whereKey: #"Utente" matchesKey:#"Da_User" inQuery:QueryForFriend];
PFQuery *normalPostByUser = [PFQuery queryWithClassName:#"Post"];
[normalPostByUser whereKey: #"FLASH_POST" equalTo: [NSNumber numberWithBool: NO]];
[normalPostByUser whereKey: #"Utente" equalTo: [PFUser currentUser]];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[QueryYES,normalPostByFriends,normalPostByUser ]];
[query includeKey:#"Author"];
[query orderByDescending:FF_CREATEDAT];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
if (!error) {
NSLog(#"%#", results);
ArrayforPost = [[NSMutableArray alloc] init];
for (PFObject *object in results) {
[ArrayforPost addObject:object];
}
[self.FFTableView reloadData];
}
}];
}
The problem is handled by making another query to display current user's normal post and modify QueryForFriend for a correct query