聚合名称的排序未保留在响应中

ordering of agg names not retained in the response

我正在执行弹性查询并使用 REST 调用读取 java 代码中的响应。 当我阅读响应时,字段顺序 - 200、204、4xx、5xx 未按响应中的顺序返回。

在下面找到放置的示例请求

GET appl-activity*/_search
{
  "size": 0,
  "aggs": {
    "group_by_daterange": {
      "range": {
        "field": "Date",
        "ranges": [
          {
            "from": "Fri Oct 23 02:54:26 2020 -0400",
            "to": "Mon Oct 26 05:54:26 2020 -0400"
          }
        ]
      },
      "aggs": {
        "byapplication": {
          "terms": {
            "field": "application.keyword",
            "size": 1000
          },
          "aggs": {
            "by200": {
              "sum": {
                "field": "200"
              }
            },
            "by204": {
              "sum": {
                "field": "204"
              }
            },
            "by4xx": {
              "sum": {
                "field": "4xx"
              }
            },
            "by5xx": {
              "sum": {
                "field": "5xx"
              }
            }
          }
        }
      }
    }
  }
}

返回响应:-

{
  "took" : 35,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1173,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_daterange" : {
      "buckets" : [
        {
          "key" : "Fri Oct 23 06:54:26 2020 +0000-Mon Oct 26 09:54:26 2020 +0000",
          "from" : 1.603436066E12,
          "from_as_string" : "Fri Oct 23 06:54:26 2020 +0000",
          "to" : 1.603706066E12,
          "to_as_string" : "Mon Oct 26 09:54:26 2020 +0000",
          "doc_count" : 30,
          "byapplication" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "SITE",
                "doc_count" : 20,
                "by4xx" : {
                  "value" : 1.0
                },
                "by5xx" : {
                  "value" : 0.0
                },
                "by204" : {
                  "value" : 0.0
                },
                "by200" : {
                  "value" : 5342.0
                }
              },
              {
                "key" : "MOBILE",
                "doc_count" : 10,
                "by4xx" : {
                  "value" : 0.0
                },
                "by5xx" : {
                  "value" : 0.0
                },
                "by204" : {
                  "value" : 0.0
                },
                "by200" : {
                  "value" : 5635.0
                }
              }
            ]
          }
        }
      ]
    }
  }
}

我希望响应代码的顺序与请求中的顺序相同。请帮助我??

{
  "key": "MOBILE",
  "doc_count": 10,
  "by200": {
    "value": 5635
  },
  "by204": {
    "value": 0
  },
  "by4xx": {
    "value": 0
  },
  "by5xx": {
    "value": 0
  }
}

与数组不同,JSON 字典不保证任何顺序。这意味着没有规范会强制 ElasticSearch 或任何其他 JSON-in/JSON-out 界面保留输入顺序。

虽然这很不幸,但某些系统(例如 stripe)在返回给客户端之前会更加努力地按字母顺序对响应键进行排序。


话虽如此,我过去常常根据我想要的顺序在 agg 键名称前加上一个字母数字字符组合来解决这个问题:

{
  "1__myAggName": { ... },
  "2__myAggName": { ... },
   ...
}

然后在客户端,我会简单地对聚合键进行排序并放弃前缀。

但最近我倾向于使用 aggregation metadata 来放置订单和其他信息。这大大提高了我所有 post-processing 步骤的透明度和可读性:

{
  ...
  "byapplication": {
    "terms": {
      "field": "application.keyword",
      "size": 1000
    },
    "aggs": {
      "by200": {
        "meta": {       <--
          "index": 0
        },
        "sum": {
          "field": "200"
        }
      },
      "by204": {
        "meta": {      <--
          "index": 1
        },
        "sum": {
          "field": "204"
        }
      },
      "by4xx": {
        "meta": {
          "index": 2
        },
        "sum": {
          "field": "4xx"
        }
      },
      "by5xx": {
        "meta": {
          "index": 3
        },
        "sum": {
          "field": "5xx"
        }
      }
    }
  }
}