Elasticsearch:分组到桶中,每个桶减少到一个文档,对这些文档进行分组

时间:2017-01-25 17:54:12

标签: elasticsearch

我正在寻找一种如何使用弹性搜索来计算网页跳出率的方法。

我们采用以下简化结构收集数据

{"id":"1", "timestamp"="2017-01-25:15:23", "sessionid"="s1", "page"="index"}
{"id":"2", "timestamp"="2017-01-25:15:24", "sessionid"="s1", "page"="checkout"}
{"id":"3", "timestamp"="2017-01-25:15:25", "sessionid"="s1", "page"="confirm"}

{"id":"4", "timestamp"="2017-01-25:15:26", "sessionid"="s2", "page"="index"}
{"id":"5", "timestamp"="2017-01-25:15:27", "sessionid"="s2", "page"="checkout"}

{"id":"6", "timestamp"="2017-01-25:15:26", "sessionid"="s3", "page"="product_a"}
{"id":"7", "timestamp"="2017-01-25:15:28", "sessionid"="s3", "page"="checkout"}

对于此样本,分析结果应为:

  

2/3的用户在结帐页面上迷路了。

     

1/3的用户在确认页面上迷路了

更正式地说,我正在寻找一种通用方法,如何在弹性查询中实现以下算法:

  1. 按字段分组文档
  2. 按第二个字段对每个组(存储桶)进行排序,并缩小到最顶层的文档
  3. 将所有这些剩余文档分组为第三个字段
  4. 按文件数排序分组
  5. 我的第一次尝试是使用术语聚合,然后是 top_hits聚合解决此问题,最后使用 terms_pipeline aggregation 将页面分组。

    (简化聚合结构)

    aggs
        terms
            field: sessionid
            aggs
                top_hits
                    sort:timestamp desc
                    size: 1
        terms_pipeline
            bucket_path: terms>top_hits
            field: page
    

    ...但不幸的是,没有像 terms_pipeline aggregation 这样的东西。我的坏。

    有关替代方法的任何想法吗?

1 个答案:

答案 0 :(得分:0)

也许我误解了某些内容,但如果您愿意知道用户的弹跳位置,因为所有网页都在一个序列中,您只需在terms字段上设置page聚合(即可知道)访问了哪些页面)和cardinality字段上的sessionid一个(了解您拥有多少个不同的唯一会话)。在这种情况下,cardinality(sessionid)将产生3.

然后,由于所有页面都在一个序列中,我认为你并不需要知道给定会话中发生了什么。

在您的示例中,从terms(page)聚合,您知道有3个用户登陆结帐页面,但只有一个用户进入确认页面。使用会话的基数,这隐含意味着2个用户(总共3个会话 - 1个确认页面点击)在结帐页面上退回。