Start a new topic

Geo Near Returning First Results Incorrectly

Hello All,



So I recently started having an issue with my function calls to the database are not returning the first results correctly. This particular function call the first database call returns results that are furthest away from the user. Which is the complete opposite that it should be. If I go back on the screen and then forward again it loads it perfectly and all calls on that function from then on work fine as well. I cannot figure out what the issue is with it. I am currently using a regex with the nearsphere in an AND query. I currently have an app in the app store that has the same code. It is working fine so I am at a loss as to what could be causing this. Here is the code below:



-(void) callToDatabaseOnPlaceCollectionUsingCurrentLocationWithSkipLimit: (int) newSkipLimit

usingDistance: (BOOL) useMaxDistance

withChannelQueryName: (NSString *) channelName

withDelegate: (id) delegate {



//pointer to a query

KCSQuery *geoQuery, *mutiQuery, *channelQuery;



KCSAppdataStore *placesStore = [KCSAppdataStore storeWithOptions:@{ KCSStoreKeyCollectionName : @"places",

KCSStoreKeyCollectionTemplateClass : [Place class]}];



//if distance is 0 then it will get everything from the database.

if (useMaxDistance) {

//this is the code that gets stuff from the database that is up to a certain distance away.

geoQuery = [KCSQuery queryOnField:KCSEntityKeyGeolocation usingConditionalsForValues: kKCSNearSphere,

@[@(currentLocation.coordinate.longitude), @(currentLocation.coordinate.latitude)],

kKCSMaxDistance, @(maxDistance), nil];

} else {

//this code is for getting a query that has no distance limit

geoQuery = [KCSQuery queryOnField:KCSEntityKeyGeolocation

usingConditional:kKCSNearSphere

forValue:@[@(currentLocation.coordinate.longitude), @(currentLocation.coordinate.latitude)]];

}



//setup the compound query

//setup the compound query

channelQuery = [KCSQuery queryOnField:@"channels" withRegex:channelName];

mutiQuery = [[KCSQuery alloc] init];

[mutiQuery addQuery:geoQuery];

[mutiQuery addQuery:channelQuery];



//set the skip amount, and limit amount

mutiQuery.limitModifer = [[KCSQueryLimitModifier alloc] initWithLimit:newSkipLimit];

mutiQuery.skipModifier = [[KCSQuerySkipModifier alloc] initWithcount:0];



//send the request to the database.

[placesStore queryWithQuery:mutiQuery withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil){

if ([delegate respondsToSelector:@selector(databaseCallDidFinishWithObjects:withErrors:)]) {

[delegate databaseCallDidFinishForUpdatesWithObjects:objectsOrNil withErrors:errorOrNil];

}

} withProgressBlock:^(NSArray *objects, double percentComplete) {

//NSLog(@"progress = %f", percentComplete);

}];

}





Thanks for any ideas or help on the subject,

Sean

I redesigned my algorithm and it seemed to fix it.... I hope hahaha. Its just wired that nothing about the code that handled the database calls had changed.
What was the redesign?
Avatar-1384280157



Well I had 4 functions to make calls my single collection in the database. One took advantage of the skip the other used the limit modifier. Then there was two variations one that used channel name and one that did not. I combined them all into one function with the same functionality. I am guessing it was something to do with the skip and limit but I am just not sure.

Here is the code for those with a similar issue and not sure how to fix it:









-(void) callToDatabaseOnPlaceCollectionUsingCurrentLocationWithSkip: (int) skip

withSkipLimit: (int) skipLimit

withChannelQueryName: (NSString *) channelName

withDelegate: (id) delegate {

//pointer to a query

KCSQuery *geoQuery = nil, *mutiQuery = nil, *channelQuery = nil;



KCSAppdataStore *placesStore = [KCSAppdataStore storeWithOptions:@{ KCSStoreKeyCollectionName : @"places",

KCSStoreKeyCollectionTemplateClass : [Place class]}];



geoQuery = [KCSQuery queryOnField:KCSEntityKeyGeolocation

usingConditional:kKCSNearSphere

forValue:@[@(currentLocation.coordinate.longitude), @(currentLocation.coordinate.latitude)]];



if (channelName != nil) {

//setup the compound query

channelQuery = [KCSQuery queryOnField:@"channels" withRegex:channelName];

mutiQuery = [[KCSQuery alloc] init];

[mutiQuery addQuery:geoQuery];

[mutiQuery addQuery:channelQuery];

}



//set the skip amount, and limit amount

(mutiQuery == nil ? geoQuery : mutiQuery).limitModifer = [[KCSQueryLimitModifier alloc] initWithLimit:skipLimit];

(mutiQuery == nil ? geoQuery : mutiQuery).skipModifier = [[KCSQuerySkipModifier alloc] initWithcount:skip];



//send the request to the database.

[placesStore queryWithQuery:mutiQuery == nil ? geoQuery : mutiQuery

withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil){

if ([delegate respondsToSelector:@selector(databaseCallDidFinishWithObjects:withErrors:isUpdate:)]) {

[delegate databaseCallDidFinishWithObjects:objectsOrNil withErrors:errorOrNil isUpdate: skip == 0 ? true : false];

}

} withProgressBlock:^(NSArray *objects, double percentComplete) {

//NSLog(@"progress = %f", percentComplete);

}];

}
I think I may have found the issue. It happened again when I made KCSAppDataStore a class wide variable. Why would this be the case? Also for caching to work right does the KCSCachedStore need to be a class wide variable or will it deal with it automatically?
Nope that's not it, I am getting it randomly now. But it seems to be pretty rare. Once every 10 "first" calls?



Any ideas???
It only seems to happen if I do a query with my geoquery, I have not had it mess up with the mutiquery.... yet.
We don't really have an answer about why the query sometimes returns different data. My best guess is that it is a mongo issue related to how the data is loaded from a "cold" state in order to compute the results of the query.



As for the caches - there is a single cache per backend collection. Any cached store object shares this cache, and the cache policy of the store determines how data is added or read from the cache.
Your best bet is to do a single geo-query and then either filter the data locally or use the ids from the first query in an kKCSIn query with the other parameters.
Login or Signup to post a comment