# Aggregation over array

**URL:** <https://discuss.elastic.co/t/aggregation-over-array/374511>\
**Category:** Kibana\
**Tags:** aggregations\
**Created:** [February 13, 2025, 3:00pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511 "2025-02-13T15:00:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ddoroshenko](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@ddoroshenko](https://discuss.elastic.co/u/ddoroshenko)\
**Post date:** [February 13, 2025, 3:00pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/1 "2025-02-13T15:00:43Z")

</div>

Hi,

I have a document like this

```auto
{
  "ip": [
    "192.168.1.1",
    "192.168.1.2"
  ]
}

```

Is it possible to make aggregation over value at zero position in the array? Something like this?

```auto
{
  "aggs": {
    "my_aggregation": {
     "cardinality": {
        "field": "ip.0"
      }
    }
  }
}

```

I want to use this aggregation for query in a Watcher

UPD: `ip` field has `keyword` type

---

<div class="post-metadata">

**Author:** ![Marco\_Liberati](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/marco_liberati/32/82953_2.png) [@Marco\_Liberati](https://discuss.elastic.co/u/Marco_Liberati)\
**Post date:** [February 13, 2025, 3:33pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/2 "2025-02-13T15:33:49Z")

</div>

Hi @ddoroshenko

not exactly like that, but you could achieve what you are looking for with Runtime fields or via ES|QL.

## Runtime fields approach

In this case define a `ip0` field as runtime field with something like the following in painless:

```auto
def ips = doc['ip'];
if(ips.length > 0){
    if(ips.length === 1) {
        emit(ips.value);
    } else {
        emit(ips[0]);
    }
}

```

Now use the `ip0` field to perform your aggregations in your viz.

## ES|QL

You can use the [MV\_FIRST](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-functions-operators.html#esql-mv_first) function in ES|QL to extract the first value and then perform an aggregation

```auto
FROM index | STATS DISTINCT_COUNT(MV_FIRST(ip)) ...

```

---

<div class="post-metadata">

**Author:** ![ddoroshenko](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@ddoroshenko](https://discuss.elastic.co/u/ddoroshenko)\
**Post date:** [February 13, 2025, 3:41pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/3 "2025-02-13T15:41:21Z")

</div>

@Marco_Liberati thank you for your response, but I'm afraid it's not suitable for me.

I want to use this aggregation in a Watcher with another fields

---

<div class="post-metadata">

**Author:** ![ahmed\_charafouddine](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ahmed_charafouddine/32/45129_2.png) [@ahmed\_charafouddine](https://discuss.elastic.co/u/ahmed_charafouddine)\
**Post date:** [February 13, 2025, 4:00pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/4 "2025-02-13T16:00:40Z")

</div>

Here is an example that may work :

```auto
POST test/_doc
{
  "ip": [
    "192.168.1.1",
    "192.168.1.2"
  ]
}

POST test/_search
{
    "size": 0,
  "runtime_mappings": {
    "ip0": {
      "type": "keyword",
      "script": {
        "source": """
            if (doc['ip.keyword'].size() > 0) { 
                emit(doc['ip.keyword'][0]); 
            }
        """
      }
    }
  },
  "aggs": {
    "term": {
      "terms": {
        "field": "ip0"
      }
    }
  }
}

```

Response :

```auto
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "term": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "192.168.1.1",
          "doc_count": 1
        }
      ]
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![RainTown](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/raintown/32/140206_2.png) [@RainTown](https://discuss.elastic.co/u/RainTown)\
**Post date:** [February 13, 2025, 4:07pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/5 "2025-02-13T16:07:58Z")

</div>

an ingest pipeline, enriching the doc by adding a specific ip0 field ?

---

<div class="post-metadata">

**Author:** ![ddoroshenko](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@ddoroshenko](https://discuss.elastic.co/u/ddoroshenko)\
**Post date:** [February 13, 2025, 4:25pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/6 "2025-02-13T16:25:46Z")

</div>

I tried

```auto
aggs:
  cardinality:
    script:
      lang: painless
      source: params['_source']['ip'][0]

```

But i get an error

```auto
Attempting to address a non-array-like type as an array

```

But when I do

```auto
script_fields:
  ip0:
    script:
      lang: painless
      source: params['_source']['ip'][0]

```

I get

```auto
ip0: [192.168.1.1]

```

---

<div class="post-metadata">

**Author:** ![ddoroshenko](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@ddoroshenko](https://discuss.elastic.co/u/ddoroshenko)\
**Post date:** [February 13, 2025, 4:36pm UTC](https://discuss.elastic.co/t/aggregation-over-array/374511/7 "2025-02-13T16:36:32Z")

</div>

Well,  
Actually I have multi type filed `ip` and `ip.keyword`

So this works for me

```auto
aggs:
  cardinality:
    script:
      lang: painless
      source: doc['ip.keyword'][0]

```
