在弹性搜索中使用嵌套字段执行多字段/多维聚合

Perform multi-field / multi-dimensional aggregations with nested fields in Elastic Search

我正在跟踪少数学生的出勤情况。我将他们的详细信息存储在索引中,如下所示。

“条目”中的每个文档几乎没有其他字段。以下数据显示学生在“星期一”参加了 6 类。

“条目”的类型是“嵌套”

     {
      reg_id: 1111,
      "entires" : [
        {
          id: "123"
          day: 'Monday'
        },
        {
          id: "1234",
          attendance: true
        },
        {
          id: "12345",
          classes_attended: 6
        }
      ],
    }

我想要每个 classes_attended 学生每天的人数。

例如“为“星期一”找到了 72 个学生的条目,他们参加了 6 类”

所需输出示例 - 这只是一个示例,如果更改输出模式,我完全没问题。

    [
      {
        "day" : "monday", 
        "classes_attended": 6,
        count: 4
      },
      {
        "day" : "monday", 
        "classes_attended": 1,
        count: 5
      },
      {
        "day" : "tuesday", 
        "classes_attended": 5,
        count: 2
      },
      {
        "day" : "tuesday", 
        "classes_attended": 6,
        count: 1
      }
    ]

不确定如何开始聚合查询:

我尝试了以下查询,但我知道它不是正确的解决方案

"aggs": {
    "attendance_aggs": {
      "nested": {
        "path": "entries"
      },
      "aggs": {
        "days": {
          "terms": {
            "field": "entries.day"
          },
          "aggs": {
          "attended": {
            "reverse_nested": {},
            "aggs":{
              "class_attended_day": {
                "terms": {
                  "field": "entries.classes_attended"
                },
                "aggs": {
                  "class_attended_days_count": {
                    "reverse_nested": {},
                    "aggs": {
                      "classes_attended_final": {
                        "cardinality": {
                          "field": "entries.class_attended"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
        }
      }
    }
  }

不清楚顶级对象是什么,所以我假设它是“每天的学生出勤条目”。我也不确定 entries.ids 代表什么,但我假设您稍后会需要它们,所以我会保持它们不变。

现在,由于您的 entries 对象的共同点是 id,因此可以将它们解耦。这意味着只有当您 在需要保留其 属性连接 的所有对象之间共享某些属性 时,您才应该使用 nested。由于我在您的 aggs 中没有看到 entries.id,我建议您对映射进行以下调整:

PUT students
{
  "mappings": {
    "properties": {
      "day": {                ------------
        "type": "keyword"                |
      },                                 |
      "attendance": {                    |                                
        "type": "boolean"                | <--
      },                                 |
      "classes_attended": {              |
        "type": "integer"                |
      },                     ------------
      "entries": {
        "type": "nested",
        "properties": {
          "day": {
            "type": "keyword",
            "copy_to": "day"               <--
          },
          "attendance": {
            "type": "boolean",
            "copy_to": "attendance"        <--
          },
          "classes_attended": {
            "type": "integer",
            "copy_to": "classes_attended"  <--
          }
        }
      }
    }
  }
}

这是您的查询:

GET students/_search
{
  "size": 0,
  "aggs": {
    "days": {
      "terms": {
        "field": "day"
      },
      "aggs": {
        "classes_attended": {
          "terms": {
            "field": "classes_attended"
          },
          "aggs": {
            "student_count": {
              "cardinality": {
                "field": "_id"
              }
            }
          }
        }
      }
    }
  }
}

然后可以 post 将响应处理成您喜欢的任何内容。


编辑

您可以劫持 reverse_nested 但在引用其他嵌套条目时需要返回它:

GET students/_search
{
  "size": 0,
  "aggs": {
    "attendance_aggs": {
      "nested": {
        "path": "entries"
      },
      "aggs": {
        "days": {
          "terms": {
            "field": "entries.day"
          },
          "aggs": {
            "attended": {
              "reverse_nested": {},
              "aggs": {
                "class_attended_day": {
                  "nested": {
                    "path": "entries"
                  },
                  "aggs": {
                    "class_attended_day": {
                      "terms": {
                        "field": "entries.classes_attended"
                      },
                      "aggs": {
                        "classes_attended_final": {
                          "cardinality": {
                            "field": "entries.classes_attended"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}