elasticsearch 由多个字段聚合

elasticsearch aggregate by multiple fields

我是 ElasticSearch 的新手,它看起来很棒,但我仍然需要一些范式改变才能完全理解如何使用它。

我的项目是一个带有仪表板的调查平台。 一项调查有多个 "screens"(问题),每个屏幕都有多个可能的答案 - 用户选择一个并在完成调查后提交。

假设我有一个如下所示的文档(代表用户进行的一项调查):

{
    "survey_station_id": "199",
    "survey_id": "905",
    "survey_unique_identifier": "2016-05-11 08:45:34-e4c080d90264e47a1fdb2d021ca52d3a",
    "current_timestamp": 1462949134,
    "survey_timestamp": "1462949115",
    "answers": [{
        "screen_id": "9429",
        "answer_id": "4"
    }, {
        "screen_id": "9428",
        "answer_id": "3"
    }, {
        "screen_id": "9431",
        "answer_id": "0",
        "answer_text": "Very good"
    }, {
        "screen_id": "10819",
        "answer_id": "10742"
    }, {
        "screen_id": "10820",
        "answer_id": "0",
        "answer_text": "dan@somewhere.com"
    }, {
        "screen_id": "10821",
        "answer_id": "9"
    }, {
        "screen_id": "10822",
        "answer_id": "5"
    }, {
        "screen_id": "10823",
        "answer_id": "10745"
    }]
}

我的数据库(或索引)中有大量这样的文档。

在我的仪表板中,我想按屏幕显示细分并计算每个答案的数量,这会告诉我:

{
    screen_id: 9429,
    answers: [{
        answer_id: 1,
        doc_count: 150
    }, {
        answer_id: 2,
        doc_count: 23
    }],
    screen_id: 9428,
    answers: [{
        answer_id: 1,
        doc_count: 78
    }, {
        answer_id: 2,
        doc_count: 96
    }]
}

我怎样才能完成那个或类似的?我的文档结构是否可行且容易,或者我是否应该对其进行一些操作以提高此类需求的效率?

提前致谢

请注意,Kibana(目前)不支持嵌套文档,但如果您要构建自己的仪表板,那么我更喜欢嵌套解决方案而不是完整的 "flat" 解决方案。例如,它可以更轻松地仅计算根文档的统计信息并在必要时忽略屏幕。

将子文档索引为 "nested" 后,您需要在聚合查询中包含这些元素:

  1. Nested aggregation
  2. Terms aggregationscreen_id
  3. answer_id
  4. 上的其他术语聚合

一定要对术语聚合设置一些合理的限制,否则你可能会遇到 combinatorial explosion。另请注意,如果您只对某些屏幕感兴趣,则可以在术语聚合上设置 "include" 和 "exclude" 规则。实际上,我想您会希望对 survey_id 进行筛选,因为汇总不同调查的结果没有意义(除非 screen_id 是唯一的)。