【问题标题】:Elasticsearch Geo Distance queryElasticsearch 地理距离查询
【发布时间】:2015-10-03 05:06:08
【问题描述】:

geo_point 的正确映射中,我有一个与它们相关联的纬度和经度的地点列表

我还有一个查询成功返回基于地理距离的结果,如下所示:

{
  "filter": {
    "geo_distance": {
      "distance": "30mi",
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      }
    }
  },
  "sort": {
    "_geo_distance": {
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      },
      "order": "asc",
      "unit": "mi",
      "mode": "min"
    }
  },
  "from": 0,
  "size": 500
}

因此,当前返回的结果在所提供的纬度和经度的 30 英里范围内。这很好用。

我正在为下一步而苦苦挣扎,我希望有人能指出我正确的方向。

每个地方都有一个名为distance 的字段,它是一个整数。这是一个地方愿意前往客户的最大距离。因此,如果距离为20(英里),但其经纬度计算为超过 20 英里,则应将其排除在结果之外。

返回结果如下:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": null,
    "hits": [
      {
        "_index": "test",
        "_type": "places",
        "_id": "AUtvK2OILrMWSKLclj9Z",
        "_score": null,
        "_source": {
          "id": "1",
          "name": "Chubby Company",
          "summary": "",
          "content": "",
          "locations": [
            {
              "lat": 51.8200763,
              "lon": 0.5264076
            }
          ],
          "address": [
            {
              "addr1": "xxxx",
              "addr2": "",
              "town": "MyTown",
              "county": "Essex",
              "postcode": "XX1 2XX",
              "tel1": "01111 111111",
              "tel2": "",
              "email": null
            }
          ],
          "website": "",
          "media": {
            "logo": "",
            "image": "",
            "video": ""
          },
          "product_ids": [
            "1",
            "3",
            "2"
          ],
          "distance": "20"
        },
        "sort": [
          0.031774582056958885
        ]
      }
    ]
  }
}

sort 对象是以英里为单位的距离,因此上面的结果是距客户端 0.03 英里。

我正在尝试利用它来检查使用结果的记录以将其从结果中排除,但这是我失败的地方。

我尝试了不同的组合:

"script": {
  "script": "doc['distance'].value < doc['sort'].value"
}

与查询结合起来是这样的:

{
  "filter": {
    "geo_distance": {
      "distance": "30mi",
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      }
    }
  },
  "sort": {
    "_geo_distance": {
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      },
      "order": "asc",
      "unit": "mi",
      "mode": "min"
    }
  },
  "filtered": {
    "filter": {
      "script": {
        "script": "doc['distance'].value < doc['sort'].value"
      }
    }
  },
  "from": 0,
  "size": 500
}

但我得到一个错误:

SearchPhaseExecutionException[未能执行阶段[查询],所有 shards failed ...解析失败[没有元素解析器[过滤]

任何建议都会很棒。

更新

尝试这个也失败了:

{
  "filter": {
    "geo_distance": {
      "distance": "30mi",
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      }
    },
    "script": {
      "script": "_source.distance < sort.value"
    }
  },
  "sort": {
    "_geo_distance": {
      "companies.locations": {
        "lat": "51.8801595",
        "lon": "0.577141"
      },
      "order": "asc",
      "unit": "mi",
      "mode": "min"
    }
  },
  "from": 0,
  "size": 500
}

嵌套:ElasticsearchParseException[预期的字段名称,但得到 START_OBJECT \"script\"]; }]","状态":400}

【问题讨论】:

  • “这是一个地方愿意前往客户的最大距离” - 这是什么科幻物理魔法?

标签: elasticsearch


【解决方案1】:

我有一个类似的问题,我想为每个记录有一个条件距离,这些记录在数据中存储了这个值(对我来说是 searchRadius)。我最终在 Java 中使用了 AndFilterBuilder 和 ScriptFilterBuilder 类,因此 AndFilterBuilder 有一个包含 GeoDistanceFilterBuilder 和 ScriptFilterBuilder 的数组。

{
    "from": 0,
    "size": 20,
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
            },
            "filter": {
                "and": {
                    "filters": [
                        {
                            "geo_distance": {
                                "location": [
                                    -104.99230194091797,
                                    39.74000930786133
                                ],
                                "distance": "3000mi"
                            }
                        },
                        {
                            "script": {
                                "script": "doc['location'].arcDistanceInMiles(39.74000930786133, -104.99230194091797) < doc['searchRadius'].value"
                            }
                        }
                    ]
                }
            }
        }
    },
    "fields": "_source",
    "script_fields": {
        "distance": {
            "script": "doc['location'].distance(39.74000930786133, -104.99230194091797)"
        }
    },
    "sort": [
        {
            "_geo_distance": {
                "location": [
                    -104.99230194091797,
                    39.74000930786133
                ],
                "unit": "mi"
            }
        }
    ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多