如何按汇聚值筛选?

时间:2019-02-11 18:15:20

标签: elasticsearch aggregation elasticsearch-aggregation

我需要一个查询,该查询仅返回具有1个存储桶的结果。

下面的查询向我返回按天分组的访问者的访问数据。

{
    "size" :  0,
    "query" : {
        "filtered" : {
            "filter" : {
                "bool" : {
                    "must" : [
                        {
                            "range" : {
                                "start_time" : {
                                    "gte" : "2019-02-06 00:00:00",
                                    "lte" : "2019-02-11 23:59:59"
                                }
                            }
                        }
                    ]
                }
            }
        }
    },
    "aggs" : {
        "UNIQUE" : {
            "terms" : {
                "size" : 0,
                "field" : "username"
            },
            "aggs" : {
                "visits" : {
                    "date_histogram" : {
                        "field" : "start_time",
                        "interval" : "day",
                        "format" : "yyyy-MM-dd"
                    }
                }
            }
        }
    }
}

我需要知道在此期间哪些仅返回了一次。因此,当您只有1个存储桶时,它是一个。并且如果访问了超过一天(存储桶> 1),则表明它是RECURRENT。

2 个答案:

答案 0 :(得分:1)

如果我的理解正确,那么您需要一个users的列表,这些列表有一个唯一的日期或喜欢在特定时间范围内只访问过一次,并且希望同时提供两个详细信息,{{1} }和date放在username中。

我已经创建了一个示例映射,示例文档,聚合查询及其在响应中的显示方式

映射:

aggregation

样本文档:

您可以看到我创建了6个文档,其中PUT mytest { "mappings": { "mydocs": { "properties": { "username": { "type": "keyword" }, "start_time": { "type": "date", "format": "yyyy-MM-dd" } } } } } 在同一日期访问了两次,Jack在两个不同的日期访问了站点,而JohnJane在以下日期仅访问了一次我将为其编写汇总的时间范围。

Rob

更新的汇总请求

注意,我又添加了两个用户名分别为POST mytest/mydocs/1 { "username": "john", "start_time": "2018-08-01" } POST mytest/mydocs/2 { "username": "john", "start_time": "2018-08-01" } POST mytest/mydocs/3 { "username": "jane", "start_time": "2018-08-01" } POST mytest/mydocs/4 { "username": "rob", "start_time": "2018-08-01" } POST mytest/mydocs/5 { "username": "jack", "start_time": "2018-08-01" } POST mytest/mydocs/6 { "username": "jack", "start_time": "2018-08-02" } 的文档,该文件分别在两个不同的日期访问该网站,用户名Jack则访问了该网站同一天两次

John

响应

POST mytest/_search
{
  "size": 0,
  "query": {
    "range": {
      "start_time": {
        "gte": "2017-08-01",
        "lte": "2019-08-01"
      }
    }
  },
  "aggs": {
    "myterms": {
      "terms": {
        "size": 100,
        "field": "username"
      },
      "aggs": {
        "visit_date": {
          "date_histogram": {
            "field": "start_time",
            "interval" : "day",
            "format" : "yyyy-MM-dd"
          }
        },
        "count": {
          "cardinality": {
            "field": "start_time"
          }
        },
        "equal_one":{  
          "bucket_selector":{  
            "buckets_path":{  
             "count":"count.value"
            },
            "script":"params.count == 1"
          }
        }
      }
    }
  }
}

您可以看到,即使John在同一日期多次访问该站点,它现在仍会按预期出现在结果中。

让我知道您是否有任何疑问。

答案 1 :(得分:0)

发现的解决方案是:

{
    "size" :  0,
    "query" : {
        {
            "range" : {
                "start_time" : {
                    "gte" : "2019-02-11 00:00:00",
                    "lte" : "2019-02-11 23:59:59"
                }
            }
        }
    },
    "aggs" : {
        "UNIQUE" : {
            "terms" : {
                "size" : 0,
                "field" : "username"
            },
            "aggs":{
                "visit_date": {
                    "date_histogram": {
                        "field" : "start_time",
                        "interval" : "day",
                        "format" : "yyyy-MM-dd"
                    }
                },
                "count": {
                    "cardinality": {
                        "script": "new Date(doc['start_time'].value).format('yyyy-MM-dd')"
                    }
                },
                "equal_one":{  
                    "bucket_selector":{  
                        "buckets_path":{  
                            "count":"count.value"
                        },
                        "script":"count == 1"
                    }
                }
            }
        }
    }
}

但是性能仍然是一个问题。在大约有100万条记录的环境中,此查询无法很好地工作。

也许某些使用脚本化指标的查询可以解决,但需要更多分析(文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html