0

以下是存储在 ElasticSearch 中的数据:

[
  {
    "id": 1,
    "class": "class 1",
    "name": "Scott",
    "scores": [
      { "year": 2022, "score": 100 },
      { "year": 2011, "score": 80 },
      { "year": 2003, "score": 70 }
    ]
  },
  {
    "id": 2,
    "class": "class 1",
    "name": "Gabriel",
    "scores": [
      { "year": 2015, "score": 90 },
      { "year": 2011, "score": 70 }
    ]
  },
  {
    "id": 3,
    "class": "class 2",
    "name": "Scott",
    "scores": [
      { "year": 2022, "score": 100 },
      { "year": 2021, "score": 100 },
      { "year": 2003, "score": 80 }
    ]
  },
  {
    "id": 4,
    "class": "class 2",
    "name": "Pierce",
    "scores": [
      { "year": 2022, "score": 70 }
    ]
  }
]

ElasticSearch中有没有办法按特定组将分数合并/组合到一个数组中?(保留重复值)

例如:

  1. 按班级分组,会显示班级 1班级 2的成绩,只保留班级成绩字段,结果会是:
[
  {
    "class": "class 1",
    "scores": [
    { "year": 2022, "score": 100 },
    { "year": 2015, "score": 90 },
    { "year": 2011, "score": 80 },
    { "year": 2011, "score": 70 },
    { "year": 2003, "score": 70 }
    ]
  },
  {
    "class": "class 2",
    "scores": [
    { "year": 2022, "score": 100 },
    { "year": 2022, "score": 70 },
    { "year": 2021, "score": 100 },
    { "year": 2003, "score": 80 }
    ]
  }
]
  1. 按name分组,会将Scott的所有分数放入一个数组中,只保留namescores字段:
[
  {
    "name": "Scott",
    "scores": [
      { "year": 2022, "score": 100 },
      { "year": 2022, "score": 100 },
      { "year": 2021, "score": 100 },
      { "year": 2011, "score": 80 },
      { "year": 2003, "score": 80 },
      { "year": 2003, "score": 70 }
    ]
  },
  {
    "name": "Gabriel",
    "scores": [
      { "year": 2015, "score": 90 },
      { "year": 2011, "score": 70 }
    ]
  },
  {
    "name": "Pierce",
    "scores": [
      { "year": 2022, "score": 70 }
    ]
  }
]

谢谢!

4

1 回答 1

1

免责声明:系好安全带,这将是冗长的^^

TLDR;

是的,可以使用术语聚合

例如,按类分组:

您会发现一个名为byClasstype的存储桶term。Elastic 将在字段类中为每个值创建文档桶。

->class 1class 2

但是你会注意到它在这个聚合中创建了更多的聚合。

- >nestedAGGbyyearbynotes

第一个是Elastic 的特殊性

其他2个则按年进一步细分,然后分别说明。

GET /71128503/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "byClass": {
      "terms": {
        "field": "class",
        "size": 10
      },
      "aggs": {
        "nestedAGG": {
          "nested": {
            "path": "scores"
          },
          "aggs": {
            "byyear": {
              "terms": {
                "field": "scores.year",
                "size": 10
              },
              "aggs": {
                "bynotes": {
                  "terms": {
                    "field": "scores.score",
                    "size": 10
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
{
  ...

  "aggregations" : {
    "byClass" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "class 1",
          "doc_count" : 2,
          "nestedAGG" : {
            "doc_count" : 5,
            "byyear" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : 2011,
                  "doc_count" : 2,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 70,
                        "doc_count" : 1
                      },
                      {
                        "key" : 80,
                        "doc_count" : 1
                      }
                    ]
                  }
                },
                {
                  "key" : 2003,
                  "doc_count" : 1,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 70,
                        "doc_count" : 1
                      }
                    ]
                  }
                },
                {
                  "key" : 2015,
                  "doc_count" : 1,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 90,
                        "doc_count" : 1
                      }
                    ]
                  }
                },
                {
                  "key" : 2022,
                  "doc_count" : 1,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 100,
                        "doc_count" : 1
                      }
                    ]
                  }
                }
              ]
            }
          }
        },
        {
          "key" : "class 2",
          "doc_count" : 2,
          "nestedAGG" : {
            "doc_count" : 4,
            "byyear" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : 2022,
                  "doc_count" : 2,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 70,
                        "doc_count" : 1
                      },
                      {
                        "key" : 100,
                        "doc_count" : 1
                      }
                    ]
                  }
                },
                {
                  "key" : 2003,
                  "doc_count" : 1,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 80,
                        "doc_count" : 1
                      }
                    ]
                  }
                },
                {
                  "key" : 2021,
                  "doc_count" : 1,
                  "bynotes" : {
                    "doc_count_error_upper_bound" : 0,
                    "sum_other_doc_count" : 0,
                    "buckets" : [
                      {
                        "key" : 100,
                        "doc_count" : 1
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

重现

摄取数据。注意自定义映射:

  • 关键字(不应在文本类型字段上按术语分组)
  • 嵌套(弹性默认平展对象)
PUT /71128503/
{
  "settings": {},
  "mappings": {
    "properties": {
      "class": {
        "type": "keyword"
      },
      "name":{
        "type": "keyword"
      },
      "scores":{
        "type": "nested",
        "properties": {
          "score": {
            "type": "integer"
          },
          "year": {
            "type": "integer"
          }
        }
      }
    }
  }
}


POST /_bulk
{"index":{"_index":"71128503","_id":1}}
{"class":"class 1","name":"Scott","scores":[{"year":2022,"score":100},{"year":2011,"score":80},{"year":2003,"score":70}]}
{"index":{"_index":"71128503","_id":2}}
{"class":"class 1","name":"Gabriel","scores":[{"year":2015,"score":90},{"year":2011,"score":70}]}
{"index":{"_index":"71128503","_id":3}}
{"class":"class 2","name":"Scott","scores":[{"year":2022,"score":100},{"year":2021,"score":100},{"year":2003,"score":80}]}
{"index":{"_index":"71128503","_id":4}}
{"class":"class 2","name":"Pierce","scores":[{"year":2022,"score":70}]}

然后查询数据:

按类别/按名称

GET /71128503/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "byName": {           <- Name of your bucket
      "terms": {          <- Type of grouping, Elastic support many, like sum, avg on numeric value ....
        "field": "name",  <- Field you grouping on
        "size": 10
      },
      "aggs": {
        "nestedAGG": {
          "nested": {
            "path": "scores"
          },
          "aggs": {
            "byyear": {
              "terms": {
                "field": "scores.year",
                "size": 10
              },
              "aggs": {
                "bynotes": {
                  "terms": {
                    "field": "scores.score",
                    "size": 10
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
于 2022-02-15T17:33:55.793 回答