通过 AWS amplify 和 ElasticSearch 查找地理和其他字段

Posted

技术标签:

【中文标题】通过 AWS amplify 和 ElasticSearch 查找地理和其他字段【英文标题】:Find Geo and additional fields via AWS amplify and ElasticSearch 【发布时间】:2019-10-05 05:33:49 【问题描述】:

在 AWS amplify 的文档中定义了如何仅通过创建自定义解析器来搜索地理位置:

https://aws-amplify.github.io/docs/cli/graphql?sdk=js#add-a-custom-resolver-that-targets-a-dynamodb-table-from-model

但是,如何结合任何其他查询过滤器(例如某个名称)找到此位置。因此,在位置 X 中找到姓名为 X 的每个人。

我有这个模板:

"version": "2017-02-28",
"operation": "GET",
"path": "$indexPath.toLowerCase()",
"params": 
    "body": 
        "query": 
            "bool" : 
                "must" : [
                     match :  "name": $ctx.args.params.name ,
                ],
                "filter" : 
                    "geo_distance" : 
                        "distance" : "$distancekm",
                        "location" : $util.toJson($ctx.args.location)
                    
                
            
        
    

使用此架构:

input paramsStringFilterInput 
  ne: String
  eq: String
  match: String
  matchPhrase: String
  matchPhrasePrefix: String
  multiMatch: String
  exists: Boolean
  wildcard: String
  regexp: String


input ParamsInput 
  name: paramsStringFilterInput
  monday: Boolean


type ZVLConnection 
  items: [ZVL]
  total: Int
  nextToken: String


type Query 
  nearbyZVL(params: ParamsInput, location: LocationInput!, km: Int): ZVLConnection

我在这个查询中遇到了这个错误:

query getProfiles
  nearbyZVL(
    location:  
        lat:51.848388,
      lon: 5.447252
    ,
    km: 12,
    params:
      name:  match: "Ramon" 
    

  )
    total,
    items    
      id
      name
    

  




  "data": 
    "nearbyZVL": null
  ,
  "errors": [
    
      "path": [
        "nearbyZVL"
      ],
      "data": null,
      "errorType": "MappingTemplate",
      "errorInfo": null,
      "locations": [
        
          "line": 2,
          "column": 3,
          "sourceName": null
        
      ],
      "message": "Unable to parse the JSON document: 'Unexpected character ('m' (code 109)): was expecting double-quote to start field name\n at [Source: (String)\"\n\n    \"version\": \"2017-02-28\",\n    \"operation\": \"GET\",\n    \"path\": \"/zorgverlener/doc/_search\",\n    \"params\": \n        \"body\": \n            \"query\": \n                \"bool\" : \n                    \"must\" : [\n                         match :  \"name\": Ramon ,\n                    ],\n                    \"filter\" : \n                        \"geo_distance\" : \n                            \"distance\" : \"12km\",\n                            \"location\" : \"lat\":51.848388,\"lon\":5.447252\n            \"[truncated 86 chars]; line: 11, column: 28]'"
    
  ]

【问题讨论】:

你有没有想过这个问题?我正在尝试做同样的事情,但没有运气...... 【参考方案1】:

@ramon 嘿伙计,所以我设法让它与各种搜索过滤器一起使用:

架构:

type Query 
  nearByEvents(filter: SearchEventsNearbyInput, sort: SearchNearbyEventsSortInput, limit: Int, nextToken: Int): EventConnection

解析器:

set( $indexPath = "/event/doc/_search" )
#set( $distance = $util.defaultIfNull($ctx.args.filter.km, 200) )

    "version": "2017-02-28",
    "operation": "GET",
    "path": "$indexPath.toLowerCase()",
    "params": 
        "body": 
            "from": #if( $context.args.nextToken ) $context.args.nextToken #else 0 #end,
            "size": #if( $context.args.limit ) $context.args.limit #else 20 #end,
            "sort":       #if( $context.args.sort )
            [#if( !$util.isNullOrEmpty($context.args.sort.field) && !$util.isNullOrEmpty($context.args.sort.direction) )
            
                "$context.args.sort.field": 
                    "order": "$context.args.sort.direction"
                
            
            #end, "_doc"]
                #else
                    []
                #end,
            "query": 
                "bool": 
                    "must": 
                        "range": 
                        "dateTime": 
                            "gte": $ctx.args.filter.startDate,
                            "lt": $ctx.args.filter.endDate
                        
                        
                    
                    ,
                    #if( $context.args.filter.categories.size() > 0 )
                    "should": [
                    #foreach( $category in $ctx.args.filter.categories )
                        
                            "match_phrase": 
                                "categories": "$category"
                            
                        
                        #if( $foreach.hasNext ),
                        #end
                    #end
                    ], 
                    "minimum_should_match": 2
                    , #end
                    "filter": 
                        "geo_distance": 
                            "distance" :"$distancekm",
                            "distance_type": "plane",
                            "location": $util.toJson($ctx.args.filter.location)
                        
                    
                
            


        
    

.

#set( $items = [] )
#foreach( $entry in $context.result.hits.hits )
  #if( !$foreach.hasNext )
    #set( $nextToken = "$entry.sort.get(0)" )
  #end
  $util.qr($items.add($entry.get("_source")))
#end
$util.toJson(
  "items": $items,
  "total": $ctx.result.hits.total,
  "nextToken": $nextToken
)

然后我能够在仍然使用地理距离的同时使用过滤器、排序和限制进行查询

希望这会有所帮助!

【讨论】:

以上是关于通过 AWS amplify 和 ElasticSearch 查找地理和其他字段的主要内容,如果未能解决你的问题,请参考以下文章

AWS Amplify 和 Vue 路由器历史模式

防止 AWS Amplify 添加斜杠和强制重定向

通过 aws Amplify 使用 Storage 类对本机图像上传进行反应

通过 GraphQL 键检索 AWS Amplify DataStore 记录

在 AWS amplify 中重写和重定向

如何将 AWS Amplify 控制台中的现有应用程序与 AWS Amplify CLI 连接?