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

时间:2015-10-23 12:06:04

标签: 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.nameplatform.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),但是有更干净,更简单的方法来完成任务吗?

2 个答案:

答案 0 :(得分:37)

显示意图的最佳方式似乎是top hits聚合:"从每个聚合组中只选择一个文档",然后从中提取平台:

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

答案 1 :(得分:1)

如果您不一定需要获得platform.id的值,则可以使用连接两个字段scriptname的{​​{1}}来避免使用单个聚合。 url

aggs: {
  platforms: {
    terms: {script: 'doc["platform.name"].value + "," + doc["platform.url"].value'}
  }
}