具有聚合功能的Elasticsearch地理查询

问题描述 投票:0回答:1

我有一个包含用户位置的elasticsearch索引。我需要使用geohash网格通过地理边界框执行汇总查询,对于文档计数少于某个值的存储桶,我需要返回所有文档。

我该怎么做?

elasticsearch
1个回答
0
投票

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

我正在考虑以下数据:

index Def

{
  "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": "restaurent",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "location": "52.37408,4.912350",
          "name": "The golden dragon"
        }
      },
      {
        "_index": "restaurent",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "location": "52.369219,4.901618",
          "name": "Burger King"
        }
      },
      {
        "_index": "restaurent",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "location": "52.371667,4.914722",
          "name": "Wendys"
        }
      },
      {
        "_index": "restaurent",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.0,
        "_source": {
          "location": "51.222900,4.405200",
          "name": "Taco Bell"
        }
      },
      {
        "_index": "restaurent",
        "_type": "_doc",
        "_id": "5",
        "_score": 1.0,
        "_source": {
          "location": "48.861111,2.336389",
          "name": "McDonalds"
        }
      },
      {
        "_index": "restaurent",
        "_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 < 2"过滤掉所有文档

© www.soinside.com 2019 - 2024. All rights reserved.