【问题标题】:Elastic Search Geo Spatial search implementationElastic Search 地理空间搜索实现
【发布时间】:2020-09-03 07:29:56
【问题描述】:

我试图了解弹性搜索如何在内部支持地理空间搜索。

对于基本搜索,它使用倒排索引;但它如何与其他搜索条件相结合,例如在特定半径内搜索特定文本。

我想了解如何存储和查询索引以支持这些查询的内部原理

【问题讨论】:

  • “在一定范围内搜索特定文本”是什么意思?
  • 假设您正在搜索关键字“Pizza”,并且希望找到附近与您的关键字匹配的地点(餐厅等)列表
  • @java_geek 你在其他地方找到答案了吗?如果是这样,你能在这里分享吗?!

标签: elasticsearch geospatial elastic-stack inverted-index


【解决方案1】:

文本和地理查询功能相互独立。让我们举一个具体的例子:

PUT restaurants
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      },
      "menu": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

POST restaurants/_doc
{
  "name": "rest1",
  "location": {
    "lat": 40.739812,
    "lon": -74.006201
  },
  "menu": [
    "european",
    "french",
    "pizza"
  ]
}

POST restaurants/_doc
{
  "name": "rest2",
  "location": {
    "lat": 40.7403963,
    "lon": -73.9950026
  },
  "menu": [
    "pizza",
    "kebab"
  ]
}

然后将match 一个文本字段,使用geo_distance 过滤器:

GET restaurants/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "menu": "pizza"
          }
        },
        {
          "geo_distance": {
            "distance": "0.5mi",
            "location": {
              "lat": 40.7388,
              "lon": -73.9982
            }
          }
        },
        {
          "function_score": {
            "query": {
              "match_all": {}
            },
            "boost_mode": "avg",
            "functions": [
              {
                "gauss": {
                  "location": {
                    "origin": {
                      "lat": 40.7388,
                      "lon": -73.9982
                    },
                    "scale": "0.5mi"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

由于geo_distance 查询仅分配真/假值(--> score=1;仅检查位置是否在给定半径内),因此可能需要应用高斯 function_score 来提升位置更接近给定的原点。

最后,这些分数可以通过使用_geo_distance 排序来覆盖,您只需按邻近度排序(当然要保持match 查询不变):

...
  "query: {...},
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 40.7388,
          "lon": -73.9982
        },
        "order": "asc"
      }
    }
  ]
}

【讨论】:

  • 我想了解 geo_distance 如何在内部工作。通常,如果它只是文本搜索,它会在倒排索引之上工作;但是包含了 geo_distance 过滤器,处理这样的查询需要什么额外的数据结构
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2011-03-15
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多