Hi,
I have a document like this
{
"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?
{
"aggs": {
"my_aggregation": {
"cardinality": {
"field": "ip.0"
}
}
}
}
I want to use this aggregation for query in a Watcher
UPD: ip
field has keyword
type
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:
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 function in ES|QL to extract the first value and then perform an aggregation
FROM index | STATS DISTINCT_COUNT(MV_FIRST(ip)) ...
1 Like
@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
Here is an example that may work :
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 :
{
"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
}
]
}
}
}
RainTown
(Kevin Maguire)
February 13, 2025, 4:07pm
5
an ingest pipeline, enriching the doc by adding a specific ip0 field ?
1 Like
I tried
aggs:
cardinality:
script:
lang: painless
source: params['_source']['ip'][0]
But i get an error
Attempting to address a non-array-like type as an array
But when I do
script_fields:
ip0:
script:
lang: painless
source: params['_source']['ip'][0]
I get
ip0: [192.168.1.1]
Well,
Actually I have multi type filed ip
and ip.keyword
So this works for me
aggs:
cardinality:
script:
lang: painless
source: doc['ip.keyword'][0]