【问题标题】:Elasticsearch geo query with aggregation具有聚合的 Elasticsearch 地理查询
【发布时间】:2020-07-21 02:30:12
【问题描述】:

我有一个包含用户位置的弹性搜索索引。 我需要使用 geohash 网格对地理边界框执行聚合查询,对于文档计数小于某个值的存储桶,我需要返回所有文档。

我该怎么做?

【问题讨论】:

  • 到目前为止你尝试了什么?

标签: elasticsearch elasticsearch-aggregation elasticsearch-query


【解决方案1】:

由于您没有提供有关您创建的索引和用户位置的任何相关信息。

我正在考虑以下数据:

索引定义

{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}   

索引示例文档

POST _bulk

{"index":{"_id":1}}
{"location":"52.37408,4.912350","name":"The golden dragon"}
{"index":{"_id":2}}
{"location":"52.369219,4.901618","name":"Burger King"}
{"index":{"_id":3}}
{"location":"52.371667,4.914722","name":"Wendys"}
{"index":{"_id":4}}
{"location":"51.222900,4.405200","name":"Taco Bell"}
{"index":{"_id":5}}
{"location":"48.861111,2.336389","name":"McDonalds"}
{"index":{"_id":6}}
{"location":"48.860000,2.327000","name":"KFC"}

根据您的问题:

当请求详细的存储桶时,使用像 geo_bounding_box 这样的过滤器 应适用于缩小主题范围

想了解更多,可以参考这个official ES doc

  • 现在,为了通过聚合过滤基于doc_count 的数据,我们可以使用bucket_selector 管道聚合。

来自documentation

管道聚合作用于其他产生的输出 聚合而不是来自文档集,将信息添加到 输出树。

因此,计算 doc_count 所需完成的工作量将是相同的。

查询

    {
  "aggs": {
    "location": {
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 52.5225,
              "lon": 4.5552
            },
            "bottom_right": {
              "lat": 52.2291,
              "lon": 5.2322
            }
          }
        }
      },
      "aggs": {
        "around_amsterdam": {
          "geohash_grid": {
            "field": "location",
            "precision": 8
          },
          "aggs": {
            "the_filter": {
              "bucket_selector": {
                "buckets_path": {
                  "the_doc_count": "_count"
                },
                "script": "params.the_doc_count < 2"
              }
            }
          }
        }
      }
    }
  }
}

搜索结果

"hits": {
    "total": {
      "value": 6,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "location": "52.37408,4.912350",
          "name": "The golden dragon"
        }
      },
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "location": "52.369219,4.901618",
          "name": "Burger King"
        }
      },
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "location": "52.371667,4.914722",
          "name": "Wendys"
        }
      },
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.0,
        "_source": {
          "location": "51.222900,4.405200",
          "name": "Taco Bell"
        }
      },
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "5",
        "_score": 1.0,
        "_source": {
          "location": "48.861111,2.336389",
          "name": "McDonalds"
        }
      },
      {
        "_index": "restaurant",
        "_type": "_doc",
        "_id": "6",
        "_score": 1.0,
        "_source": {
          "location": "48.860000,2.327000",
          "name": "KFC"
        }
      }
    ]
  },
  "aggregations": {
    "location": {
      "doc_count": 3,
      "around_amsterdam": {
        "buckets": [
          {
            "key": "u173zy3j",
            "doc_count": 1
          },
          {
            "key": "u173zvfz",
            "doc_count": 1
          },
          {
            "key": "u173zt90",
            "doc_count": 1
          }
        ]
      }
    }
  }
}

它将根据"params.the_doc_count &lt; 2"过滤掉所有计数小于2的文档

【讨论】:

  • @ruffnecktsk 你看过我的回答了吗..你的问题解决了吗??
  • @ruffnecktsk 你有没有机会仔细阅读我的回答,期待得到你的反馈,如果有帮助,请不要忘记点赞并接受:)
猜你喜欢
  • 1970-01-01
  • 2014-05-12
  • 2022-01-18
  • 1970-01-01
  • 2014-10-22
  • 2014-11-06
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多