Start a new topic
Answered

Error message: The following filters are not supported locally: $nearSphere

Hello


I'm trying to do a query by coordinates:


  

...
var dataStore = Kinvey.DataStore.collection('games');
var query = new Kinvey.Query();
var userPosition = [8, 47]; 
query.near('_geoloc', userPosition, 10);
var stream = dataStore.find(query);
stream.subscribe(function onNext(entities) { 
...

  The collection I'm accessing by the query has a column "_geoloc" with appropriate coordinates (in []).


On executing the query I receive an error message in the onError:

code: undefined

debug: undefined

kinveyRequestId: undefined

message: "This query is not able to run locally. The following filters are not supported locally: $nearSphere"

name: "QueryError"

stack: "o@https://da189i1jfloii.cloudfront.net/js/kinvey-html5-sdk-3.11.2.min.js:8:21099…"


The closest I have found about this problem is a MongoDB statement: 


Sharded Collections

Starting in MongoDB 4.0, $nearSphere queries are supported for sharded collections.
In earlier MongoDB versions, $nearSphere queries are not supported for sharded collections; instead, for sharded clusters, you must use either the $geoNear aggregation stage and the deprecated geoNear command.


Taken from here


I know Kinvey is using mongoDB but I don't know what command Kinvey is doing/using behind "near" (based on the error message I assume: $nearSphere). Maybe the error message is related to the index on the _geolocation column?

If the error is coming from my side, please let me know. Any other query type is running fine so far.
Any help/hint is appreciated!


Regards


Best Answer

Hi Tayger,


You are correct - the quey.near() is internally using MongoDB $nearSphere operator.


Geospatial queries (queries based on geolocation) are only supported online - that is because the query itself is done by the underlying MongoDB database based on a 2dsphere index stored in the server database - therefore such queries cannot be executed offline (when using DataStoreType.Cache or DataStoreType.Sync) since they would return incorrect results.


When using DataStoreType.Cache the SDK first looks for the data stored locally on the device in order to fetch the last available data very fast and then makes a request to the backend in order to fetch the most up-to-date data. Since the first query to the local data would not fetch the correct results, an error is thrown to indicate that this query is not supported in offline mode.


Therefore when making a geospatial query, please make sure you are using DataStoreType.Network.


Regarding storing the coordinates as [long, lat] and not [lat, long] - this comes from MongoDB as noted here.


Let me know if this has help or you need further help on the matter.

Martin Apostolov


Hello Martin


Thanks a lot for this answer, it's so much appreciated! I was able to make it work with your mentioned option I was just not aware of. I was always looking in the Cache settings of the collection itself, but the it needs to be configured on accessing the collection, described here.

I have no problem with the fact that network to Internet is required for this operation.


The long/lat order is really a minor thing and no issue.


Thanks again, very helpful!


Just realised I am already doing a _geoloc query from REST API (PHP) and that works flawless:

...
$query = '{"$and":[{"game.id":{"$ne":"'.$publicid.'"}},{"release.environment":{"$ne":"A"}},{"_geoloc":{"$nearSphere":['.$longitude.','.$latitude.'],"$maxDistance":"0.006213712"}}]}&fields=game.id,game.title,game.owner,release.environment';
...

The error message occurs using Kinvey's HTML5 API (Javascript). So there must be a difference in the background doing queries on _geoloc


Regareds


Tayger,


I am assuming that you have stored '_geoloc' information correctly on the backend and the coordinates that you are using in this query code are correct.


Since you are using '.cache' datastore, I would request you to pull the data from the backend and save it to the cache before executing any query on the datastore. You will have to use the following method. In the success block of this method, try executing your query. Please check this link for more information.


var promise = dataStore.pull().then(function onSuccess(entities){
// Execute your query here
}).catch(function onError(error){
// ...
});


If this suggestion doesn't help, then just try replacing single quotes with double quotes for 'Query.near()' method and see if it makes any difference. 

query.near("_geoloc", userPosition, 10);


Let me know if none of these suggestions help. I will ask our HTML5 expert to look into this issue.




Thanks,

Pranav

Kinvey


Hello Pranav


Two very interesting changes you are offering! Sadly both wont work, error appears again....

If I understand it right the pull-feature would read ALL data before doing the query. On hundredthousands of of records this could a bit too much...


Here is the key code block with your proposed changes that still shows the error:

   

var coord = [12, 47];
var query = new Kinvey.Query();
query.near("_geoloc", coord, 10);
var dataStore = Kinvey.DataStore.collection("mycollection");
var stream = dataStore.find(query);

                var promise = dataStore.pull().then(function onSuccess(entities){
                    // Execute your query here
                    stream.subscribe(function onNext(entities) {
                        console.log (entities);
                    }, function onError(error) {
                        // Output of error message is here
                        console.log (error);
                    }, function onComplete() {
                        console.log ("completed");
                    });

                }).catch(function onError(error){
                    console.log (error);
                });

And yes, the data stored in the _geoloc columns are as they should [long, lat]. They are working well accessing from REST API (PHP). Btw. Kinvey is the first service mentioning coordinates as "long, lat". All other services that I've used so far use "lat, long", just to mention it and no issue here...


The accessed collection works with the .cache option since I haven't changed anything around that (all default).


Your help is very appreciated, thank you!

Regards

  




Hello Pranav


Could you already contact your HTML expert concerning this problem? I'm really interested in a solution. This feature was one of the main reason I decided to choose Kinvey. My project heavily depends on geolocation based queries.


Regards

Answer

Hi Tayger,


You are correct - the quey.near() is internally using MongoDB $nearSphere operator.


Geospatial queries (queries based on geolocation) are only supported online - that is because the query itself is done by the underlying MongoDB database based on a 2dsphere index stored in the server database - therefore such queries cannot be executed offline (when using DataStoreType.Cache or DataStoreType.Sync) since they would return incorrect results.


When using DataStoreType.Cache the SDK first looks for the data stored locally on the device in order to fetch the last available data very fast and then makes a request to the backend in order to fetch the most up-to-date data. Since the first query to the local data would not fetch the correct results, an error is thrown to indicate that this query is not supported in offline mode.


Therefore when making a geospatial query, please make sure you are using DataStoreType.Network.


Regarding storing the coordinates as [long, lat] and not [lat, long] - this comes from MongoDB as noted here.


Let me know if this has help or you need further help on the matter.

Martin Apostolov

Login or Signup to post a comment