一尘不染

向ElasticSearch术语聚合添加其他字段

elasticsearch

索引文件如下:

{
  id: 1, 
  title: 'Blah',
  ...
  platform: {id: 84, url: 'http://facebook.com', title: 'Facebook'}
  ...
}

我想要的是按平台计数和输出统计信息。为了进行计数,我可以将术语聚合platform.id作为字段进行计数:

aggs: {
  platforms: {
    terms: {field: 'platform.id'}
  }
}

这样,我就可以像{key: 8, doc_count: 162511}预期那样将统计数据作为多个存储桶接收到。

现在,我还能以某种方式添加到这些存储桶中吗(platform.name以及platform.url用于统计的漂亮输出)?我附带的最好的看起来像:

aggs: {
  platforms: {
    terms: {field: 'platform.id'},
    aggs: {
      name: {terms: {field: 'platform.name'}},
      url: {terms: {field: 'platform.url'}}
    }
  }
}

实际上,它可以工作,并且在每个存储桶中返回非常复杂的结构:

{key: 7,
  doc_count: 528568,
  url:
   {doc_count_error_upper_bound: 0,
    sum_other_doc_count: 0,
    buckets: [{key: "http://facebook.com", doc_count: 528568}]},
  name:
   {doc_count_error_upper_bound: 0,
    sum_other_doc_count: 0,
    buckets: [{key: "Facebook", doc_count: 528568}]}},

当然,可以从此结构中提取平台的名称和网址(例如bucket.url.buckets.first.key),但是是否有更干净,更简单的方法来完成任务?


阅读 638

收藏
2020-06-22

共1个答案

一尘不染

表示意图的最佳方法似乎是热门匹配:“从每个聚合组中仅选择一个文档”,然后从中提取平台:

aggs: {
  platforms: {
    terms: {field: 'platform.id'},
    aggs: {
      platform: {top_hits: {size: 1, _source: {include: ['platform']}}}
  }
}

这样,每个被推销的对象将看起来像:

{"key": 7,
  "doc_count": 529939,
  "platform": {
    "hits": {
      "hits": [{
       "_source": {
        "platform": 
          {"id": 7, "name": "Facebook", "url": "http://facebook.com"}
        }
      }]
    }
  },
}

有点过深(与ES一样),但是很干净: bucket.platform.hits.hits.first._source.platform

2020-06-22