在 ElasticSearch 上按距离排序

Posted

技术标签:

【中文标题】在 ElasticSearch 上按距离排序【英文标题】:Sort by distance on ElasticSearch 【发布时间】:2017-07-29 05:10:06 【问题描述】:

我在弹性搜索中有这个查询来按他们的名字获取地点:

GET places/fastfood/_search

    "from" : 0, "size" : 10, 
    "query": 
        "bool": 
         "must": [
                 "regexp":  "name": ".*name.*" ,           
                 "term" :  "location_id" : id                           
        ]
            
    

name 和 id 被替换以匹配我的需要。 现在我想获取与名称和 ID 匹配但更接近所选位置的位置。假设我在提供的 location_id(城市,区域)中没有麦当劳,我应该得到最接近该位置的位置。

我在每个城市/区域都有一个名为 location 的字段,这是一个包含纬度、经度的字符串,定义为 geo_spot。然后也将纬度和经度定义为长。像这样:

"location": "33.785400,-84.38480",
"latitude": "33.785400",
"longitude": "-84.384800",

所以我尝试添加按位置排序,像这样,但我得到错误,有问题:

GET places/fastfood/_search

    "from" : 0, "size" : 10, 
    "query": 
        "bool": 
         "must": [
                 "regexp":  "name": ".*name.*" ,           
                 "term" :  "location_id" : location_id                           
        ]
            
    ,
    "sort": [
    
      "_geo_distance": 
        "location":  
          "lat":  26.112,
          "lon": -73.998
        ,
        "order":         "asc",
        "unit":          "km", 
        "distance_type": "plane" 
      
    

我做错了什么?我应该改变什么?

错误是这样的: “错误”:“SearchPhaseExecutionException [无法执行阶段 [查询],所有分片失败;shardFailures [n6y6tjWFRrCP5MXNhEV-YA][places_v1][0]: RemoteTransportException[[Boomer][inet[/xxxx:y]][indices:数据/读取/搜索[阶段/查询]]];嵌套:SearchParseException[[places_v1][0]:查询[+name:/.hosp./+location_id:[10 TO 10]] ,from[0],size[10]: Parse Failure [Failed to parse source [\r\n \"from\" : 0, \"size\" : 10, \r\n \"query\": \r\n \"bool\": \r\n \"must\": [\r\n \"regexp\": \"name\": \".hosp.\" , \r\n \"term\" : \"location_id\" : 10 \r\n ]\r\n \r\n ,\r\n \ "排序\": [\r\n \r\n \"_geo_distance\": \r\n \"位置\": \r\n \"纬度\": 26.112,\r\n \ "lon\": -73.998\r\n ,\r\n \"order\": \"asc\",\r\n \"unit\": \"km\", \r\n \ "distance_type\": \"平面\" \r\n \r\ n \r\n\n]]];嵌套:JsonParseException[Unexpected close marker '':expected ']'(对于从 [Source: [B@4ac877f6; line: 10, column: 5] 开始的 ARRAY)\n 在 [Source: UNKNOWN;行:23,列:2]]; [n6y6tjWFRrCP5MXNhEV-YA][places_v1][1]: RemoteTransportException[[Boomer][inet[/x.x.x.x:y]][indices:data/read/search[phase/query]]];嵌套:SearchParseException[[places_v1][1]: query[+name:/.hosp./+location_id:[10 TO 10]],from[0],size[10]: 解析失败[解析源失败 [\r\n \"from\" : 0, \"size\" : 10, \r\n \"query\": \r\n \"bool\": \ r\n \"必须\": [\r\n \"regexp\": \"name\": \".hosp.\" , \r\n \"term\" : \"location_id\" : 10 \r\n ]\r\n \r\n ,\r\n \"sort\": [\r\n \r \n \"_geo_distance\": \r\n \"location\": \r\n \"lat\": 26.112,\r\n \"lon\": -73.998\r\n , \r\n \"order\": \"asc\",\r\n \"unit\": \"km\", \r\n \"distance_type\": \"plane\" \r\ n \r\n \r\n\n]]];嵌套:JsonParseException[Unexpected close marker '':expected ']'(对于从 [Source: [B@19f9b52f; line: 10, column: 5] 开始的 ARRAY)\n at [Source: UNKNOWN;行:23,列:2]]; [7i0nOGiFRl-OYX8XvL_bSQ][places_v1][2]: SearchParseException[[places_v1][2]: query[+name:/.hosp./+location_id:[10 TO 10]], from[0],size[10]: Parse Failure [Failed to parse source [\r\n \"from\" : 0, \"size\" : 10, \r\n \"query\": \r\n \"bool\": \r\n \"must\": [\r\n \"regexp\": \"name\": \".hosp. em>\" , \r\n \"term\" : \"location_id\" : 10 \r\n ]\r\n \r\n ,\r\n \"排序\": [\r\n \r\n \"_geo_distance\": \r\n \"位置\": \r\n \"纬度\": 26.112,\r\n \" lon\": -73.998\r\n ,\r\n \"order\": \"asc\",\r\n \"unit\": \"km\", \r\n \" distance_type\": \"plane\" \r\n \r\n \r\n\n]]];嵌套:JsonParseException[Unexpected close marker '':expected ']'(对于从 [Source: [B@427094b6; line: 10, column: 5] 开始的 ARRAY)\n 在 [Source: [B@427094b6;行:23,列:2]]; [n6y6tjWFRrCP5MXNhEV-YA][places_v1][3]: RemoteTransportException[[Boomer][inet[/x.x.x.x:y]][indices:data/read/search[phase/query]]];嵌套:SearchParseException[[places_v1][3]: query[+name:/.hosp./+location_id:[10 TO 10]],from[0],size[10]: 解析失败[解析源失败 [\r\n \"from\" : 0, \"size\" : 10, \r\n \"query\": \r\n \"bool\": \ r\n \"必须\": [\r\n \"regexp\": \"name\": \".hosp.\" , \r\n \"term\" : \"location_id\" : 10 \r\n ]\r\n \r\n ,\r\n \"sort\": [\r\n \r \n \"_geo_distance\": \r\n \"location\": \r\n \"lat\": 26.112,\r\n \"lon\": -73.998\r\n , \r\n \"order\": \"asc\",\r\n \"unit\": \"km\", \r\n \"distance_type\": \"plane\" \r\ n \r\n \r\n\n]]];嵌套:JsonParseException[Unexpected close marker '':expected ']'(对于从 [Source: [B@4f781e6c; line: 10, column: 5] 开始的 ARRAY)\n at [Source: UNKNOWN;行:23,列:2]]; [n6y6tjWFRrCP5MXNhEV-YA][places_v1][4]: RemoteTransportException[[Boomer][inet[/x.x.x.x:y]][indices:data/read/search[phase/query]]];嵌套:SearchParseException[[places_v1][4]: query[+name:/.hosp./+location_id:[10 TO 10]],from[0],size[10]: 解析失败[解析源失败 [\r\n \"from\" : 0, \"size\" : 10, \r\n \"query\": \r\n \"bool\": \ r\n \"必须\": [\r\n \"regexp\": \"name\": \".hosp.\" , \r\n \"term\" : \"location_id\" : 10 \r\n ]\r\n \r\n ,\r\n \"sort\": [\r\n \r \n \"_geo_distance\": \r\n \"location\": \r\n \"lat\": 26.112,\r\n \"lon\": -73.998\r\n , \r\n \"order\": \"asc\",\r\n \"unit\": \"km\", \r\n \"distance_type\": \"plane\" \r\ n \r\n \r\n\n]]];嵌套:JsonParseException[Unexpected close marker '':expected ']'(ARRAY 从 [Source: [B@586764c7; line: 10, column: 5] 开始)\n at [Source: UNKNOWN;行:23,列:2]]; ]", “状态”:400

【问题讨论】:

【参考方案1】:

这是一个语法错误,您应该使用 ] 而不是 关闭排序

【讨论】:

你能告诉我你是怎么知道的吗? 看看你的错误日志的结尾:JsonParseException[Unexpected close marker '': expected ']'

以上是关于在 ElasticSearch 上按距离排序的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:在 Elasticsearch 中按距离有效地对地理点进行排序

Elasticsearch 地理距离排序不完全/错误的顺序

SpringBoot集成ElasticSearch,实现模糊查询,批量CRUD,排序,分页,高亮

探索Elasticsearch集群API

如何在 Anylogic 上按路线(而不是距离)获取时间?

Elasticsearch学习笔记-黑马旅游网实践