Geo search on mobile

I have understood that there is no GeoSpatial search in mobile (which I cannot understand why…?).

An earlier suggestion from @priya.rajagopal is to use “bounding box” approach: Confusing GeoSpatial - so that is what I’m now trying…

I need a little more to get it working on the mobile so I hope someone can help me turn the last stone :slight_smile:

I have a data model like this (type Lake):

[
  {
    "data": {
      "key": "1002",
      "name": "Julmose",
      "points": [
        {
          "lat": 55.8358009118,
          "lon": 12.3967548701
        }
      ],
      "type": "Lake"
    }
  }
]

Which is the result from this query:

select * from data where type="Lake" limit 1

There can be more than one point in the array of lat/lon pairs.

So starting by testing with N1QL on the server I have ended up with a query that can find lakes inside a “box”:

select d.*,p.* from data d unnest points p where d.type="Lake" and 
p.lat between 55.5 and 55.6 and p.lon between 11.0 and 11.5

… I still need to do some work to calculate distances from the point where the user is and sort the result based on that.

However, I have not been able to “translate” the above query to CB Lite… - I seem not to be able to do unnest in the mobile world. So can anyone help me to create the proper CB Lite syntax to perform the same search?

Ok, I searched a little “wider” and following a couple of articles I ended up finding a way to do it :smile:

References:


Beware that there are some syntax errors in this. Use ArrayExpression instead of Expression as you can find out from this excellent article:

https://blog.couchbase.com/querying-array-collections-couchbase-mobile/

The final code looks like this snippet:

                var  _expType = Expression.Property(TYPE).EqualTo(Expression.String(typeof(Lake).Name))
                var _points = ArrayExpression.Variable("points");
                var _lat = ArrayExpression.Variable("points.lat");
                var _lon = ArrayExpression.Variable("points.lon");
                var expGeo = ArrayExpression.Any(_points).In(Expression.Property("points"))
                    .Satisfies(_lat.Between(Expression.Double(55.5), Expression.Double(55.6))
                    .And(_lon.Between(Expression.Double(11.0), Expression.Double(11.5))));
                var _condition = _expType.And(expGeo);

                using (var query = QueryBuilder.Select(
                        SelectResult.All())
                       .From(dbSource)
                       .Where(_condition)
                    )
                {
                    var result = query?.Execute()?.AllResults();
                    list.AddRange(result?.ToObjects<T>(AppConstants.DB_NAME));
                }

Obviously, I just need to fit in the real position params in the above example :smile: :innocent:

1 Like