ElasticSearch聚合GPS的交叉点

时间:2017-09-12 17:43:37

标签: elasticsearch aggregation

我已经开始想出这个了。我有时间和GPS记录:

{ID: 1,Time:"2017-01-1",gps:{lat:38.00,lon:-79.00}},
{ID: 2,Time:"2017-01-1",gps:{lat:38.00,lon:-79.00}},
{ID: 1,Time:"2017-01-2",gps:{lat:39.00,lon:-77.00}},
{ID: 2,Time:"2017-01-2",gps:{lat:20.00,lon:-20.00}},
{ID: 1,Time:"2017-01-3",gps:{lat:20.00,lon:-20.00}},
{ID: 3,Time:"2017-01-1",gps:{lat:20.00,lon:-20.00}},
..........

我有一张允许绘制圆圈和选择区域的地图。目前,我可以轻松查询和汇总在所选的任何位置中出现的记录。这是一个例子:

{
  "query": {
    "bool": {
      "should": [
        {
          "geo_distance": {
            "distance": 56100.0,
            "gps": {
              "lat": 38,
              "lon": -79
            }
          }
        },
        {
          "geo_distance": {
            "distance": 56100.0,
            "gps": {
              "lat": 39,
              "lon": -77
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "by_record_id":{
      "terms": {
        "field": "id"
      }
    }
  }
}

然而,我对如何获得选择的交集感到有点困惑。 (注意:圆圈不重叠)。从本质上讲,我想要一个已经出现在两个圆圈中的gps值的记录的汇总,并删除任何只出现在一个或没有的圆圈中的记录。例如,对于上述记录,我只想要ID = 1的聚合结果(因为ID = 2且ID = 3不会出现在两个圆圈中)。

如果我将查询更改为{“query”:{“bool”:{“must”:[...]}}},我就没有结果。因为很明显,两个地方同时没有记录。

我尝试了很多不同的东西,包括function_score(将每个位置放在函数中)和利用分数(基于不同的分数类型)。另外,我尝试了很多不同的聚合组合,包括使用top_hits过滤,基数(使用precision_threshold),带基数的bucket_selector。

这在SQL中看起来非常简单明了。请帮助弹性研究。

1 个答案:

答案 0 :(得分:0)

得到了答案!

  "aggs": {
    "ids": {
     "terms": {
       "field": "ID"
     },
    "aggs": {
     "the_filter": {
      "bucket_selector": {
        "buckets_path": {
          "the_doc_count": "_count"
        },
         "script": "params.the_doc_count >= 2"
        }
      }
    }
  }
}