Aws-mobile-appsync-sdk-js: Is there any way to have Geospatial queries?

Created on 23 Feb 2018  路  4Comments  路  Source: awslabs/aws-mobile-appsync-sdk-js

question

Most helpful comment

Like @appwiz said you can use an Elasticsearch resolver to add Geospatial queries. I don't believe the code from the presentation is on github yet but here is a snippet to help you get started.

Lets suppose you have a query type:

# This assumes there is a type named 'Store'
type Query {
   storesNear(lat: Float!, lon: Float!, distance: String!): [Store]
}

The resolver api gives you access to the full Elasticsearch DSL (which for geo queries can be found here https://www.elastic.co/guide/en/elasticsearch/reference/5.5/geo-queries.html). Use the "params" key in the request mapping template to provide that DSL that is parameterized using values in the $ctx (e.g. we are using the distance, lat, and lng values from the arguments passed via GraphQL).

#** 
    The 'params' key accepts any valid Elasticsearch DSL expression. 
    You must replace the <index> and <type> placeholder with actual values. 
*#
{
    "version":"2017-02-28",
    "operation":"GET",
    "path":"/my-es-index/stores/_search",
    "params":{
        "body": {
            "query": {
              "filtered" : {
                  "query" : {
                      "match_all" : {}
                  },
                  "filter" : {
                      "geo_distance" : {
                          "distance" : "$ctx.args.distance",
                          "location" : {
                              "lat" : $ctx.args.lat,
                              "lon" : $ctx.args.lon
                          }
                      }
                  }
              }
            }
        }
    }
}

This request mapping template will configure the call to elasticsearch which will be executed from the AppSync servers. The response mapping template will then have access to those results via $ctx.result in the template. You can simplify the structure of the result returned by Elasticsearch and coerce it into a flat list of store objects with a response mapping template like this.

#** 
    $context.result contains the full response of the Elasticsearch query.
    Select a subset of information or iterate through hits to return the
    same shape as is expected by this field.
*#
[
    #foreach($entry in $context.result.hits.hits)
        # See the Elasticsearch search api for why we do this.
        # https://www.elastic.co/guide/en/elasticsearch/reference/current/_the_search_api.html
        $util.toJson($entry.get("_source")),
    #end
]

I hope this helps. From the AppSync console's resolver form, you can select a sample template from the drop downs above the mapping templates to help you get started with this.

All 4 comments

You can construct and execute geospatial queries with the Elasticsearch resolver. Take a look at https://www.youtube.com/watch?v=mQBtbHKSdAQ for an example.

Thanks @appwiz
Is the code from the presentation available on github?

Like @appwiz said you can use an Elasticsearch resolver to add Geospatial queries. I don't believe the code from the presentation is on github yet but here is a snippet to help you get started.

Lets suppose you have a query type:

# This assumes there is a type named 'Store'
type Query {
   storesNear(lat: Float!, lon: Float!, distance: String!): [Store]
}

The resolver api gives you access to the full Elasticsearch DSL (which for geo queries can be found here https://www.elastic.co/guide/en/elasticsearch/reference/5.5/geo-queries.html). Use the "params" key in the request mapping template to provide that DSL that is parameterized using values in the $ctx (e.g. we are using the distance, lat, and lng values from the arguments passed via GraphQL).

#** 
    The 'params' key accepts any valid Elasticsearch DSL expression. 
    You must replace the <index> and <type> placeholder with actual values. 
*#
{
    "version":"2017-02-28",
    "operation":"GET",
    "path":"/my-es-index/stores/_search",
    "params":{
        "body": {
            "query": {
              "filtered" : {
                  "query" : {
                      "match_all" : {}
                  },
                  "filter" : {
                      "geo_distance" : {
                          "distance" : "$ctx.args.distance",
                          "location" : {
                              "lat" : $ctx.args.lat,
                              "lon" : $ctx.args.lon
                          }
                      }
                  }
              }
            }
        }
    }
}

This request mapping template will configure the call to elasticsearch which will be executed from the AppSync servers. The response mapping template will then have access to those results via $ctx.result in the template. You can simplify the structure of the result returned by Elasticsearch and coerce it into a flat list of store objects with a response mapping template like this.

#** 
    $context.result contains the full response of the Elasticsearch query.
    Select a subset of information or iterate through hits to return the
    same shape as is expected by this field.
*#
[
    #foreach($entry in $context.result.hits.hits)
        # See the Elasticsearch search api for why we do this.
        # https://www.elastic.co/guide/en/elasticsearch/reference/current/_the_search_api.html
        $util.toJson($entry.get("_source")),
    #end
]

I hope this helps. From the AppSync console's resolver form, you can select a sample template from the drop downs above the mapping templates to help you get started with this.

@mikeparisstuff very helpful Sir. Thank you.

Was this page helpful?
0 / 5 - 0 ratings