Table Cell Metadata

Spatialized founder Jozef Sorocin
Jozef Soročin
Updated 07/13/2025

As debated in Aggregation Data Tables , we know it's neat to treat tables of different columnar metrics with sets of row-based sub-aggregations.

The downside of this approach is having to deal with lots of iterations, lookups, and path accessors in the response JSON when trying to extract the actually presentable values.

The URL parameter filter_path offers the possibility reduce the response and thus limit which parts of the default JSON are returned. Applying it with in connection with the products aggregation from the previous chapter would mean:

POST products/_search?filter_path=aggregations.by_range.*.*.value
{
  "aggs": {
    "by_range": {
      "filter": {
         ...

yielding the reduced response:

{
  "aggregations" : {
    "by_range" : {
      "1.row|0_to_25" : {
        "2.revenue" : {
          "value" : 20.0
        },
        "1.sold_count" : {
          "value" : 1
        }
      },
      ...
    }
  }
}

filter_path can in fact be used in almost any ES request that returns JSON or YAML (?format=yaml), thus somewhat emulating the widely used command-line utility jq .

Response filtering is, however, the last step of the request making process so let's first talk about the "optimal" aggregation request structure.

Building on top of the products example , I'd like to efficiently label row- & column-based aggregations based on what they'll look like in the frontend, and keep track of the final aggregation sequence so that I don't have to use alphanumerically-prefixed aggregation names.

Any frontend-relevant attributes can be stored as key-value pairs right within each sub-aggregation's metadata. What's relevant for us is the row & column indices, plus any frontend post-processing functions that we'd want to apply to the values.

Join 200+ developers who've mastered this! Get Complete Access — €19
Already a member? Sign in here