2017-04-12 81 views
1

我试图在ElasticSearch文档中对类似于the example的聚合进行分区,但没有得到该示例的工作。分组聚合与组

该指数是填充了事件类型:

public class Event 
{ 
    public int EventId { get; set; } 
    public string SegmentId { get; set; } 
    public DateTime Timestamp { get; set; } 
} 

EventId是唯一的,并且每个事件属于特定SegmentId。每个SegmentId可以与零到多个事件相关联。

的问题是: 如何获得每个SegmentId最新EventId

我期望独特的片段的数量在1000万的范围内,而独特的事件的数量大一个或两个量级。这就是为什么我认为使用top_hits本身并不合适,因为suggested here。因此,分区。

实施例:

我已经设置了一个演示索引填入1313个文档(独特EventId),属于101不同SegmentId(即13个每段事件)。我希望下面的查询能够正常工作,但是无论我指定哪个partition数字,都会返回完全相同的结果。

POST /demo/_search 
{ 
    "size": 0, 
    "aggs": { 
    "segments": { 
     "terms": { 
     "field": "segmentId", 
     "size": 15,     <-- I want 15 segments from each query 
     "include": { 
      "partition": 0,   <-- Trying to retrieve the first partition 
      "num_partitions": 7  <-- Expecting 7 partitions (7*15 > 101 segments) 
     } 
     }, 
     "aggs": { 
     "latest": { 
      "top_hits": { 
      "size": 1, 
      "_source": [ 
       "timestamp", 
       "eventId", 
       "segmentId" 
      ], 
      "sort": { 
       "timestamp": "desc" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

如果我删除include并设置size大于101的值,我为每一个细分的最新事件。然而,我怀疑这是一个百万桶的好方法...

回答

0

原来我正在调查错误的问题......我的例子其实完美的作品。

问题是我本地的ElasticSearch节点。我不知道它出了什么问题,但是当在另一台机器上重复这个例子时,它就起作用了。但是,我无法使用当前的ES安装进行分区。因此我再次卸载并重新安装ElasticSearch,然后该示例运行。

要回答我的原始问题,我提供的例子是要走的路。我通过使用cardinality aggregate来估计产品总数,从中得出适当数量的分区,从而解决了我的问题。然后,我为每个分区打开上面的查询,并将这些文档添加到最终列表中。

1

您正在尝试做一个聚合Scroll

滚动API仅支持搜索查询,不支持聚合。如果你不想使用排名靠前的,正如你所说的,由于文件数量庞大,你可以尝试:

  1. Parent/Child方法 - 在其中创建段作为父文档和事件在子文档中。每次添加子项时,都可以更新父文档中的时间戳字段。通过这样做,您可以查询父文档,并且您将获得细分ID +最后一个事件时间戳

  2. 另一种方法是尝试仅在过去24小时内获得最高点击数。因此,您可以添加一个查询来首先过滤最近24小时,然后尝试使用top_hit获取aggs。

+0

你是正确的,我想要的是聚合上的滚动,这是不支持的。不过,我用分区解决了它(请参阅我接受的答案)。不过谢谢你的建议!他们可能在另一种情况下派上用场! (: – Reyhn