ElasticSearch Nested NumericRangeQuery usando o valor mínimo da lista para comparação
Tenho os seguintes dados:
[{
"id": "1",
"listItems": [
{
"key": "li1",
"value": 100
},
{
"key": "li2",
"value": 5000
}
]
},
{
"id": "2",
"listItems": [
{
"key": "li3",
"value": 200
},
{
"key": "li2",
"value": 2000
}
]
}]
Estou tentando fazer um filtro NumericRangeQuery para que o valor MIN em cada listItems do documento corresponda entre um intervalo. Por exemplo, meu intervalo é de 150 a 15.000.
A única maneira que conheço de escrever isso é usando uma consulta de script, mas ela não parece funcionar, pois o código ainda parece pegar qualquer valor em listItems para tentar corresponder ao intervalo em vez de pegar o MIN como eu disse para. Esta é a minha consulta:
{
"track_total_hits": true,
"from": 0,
"min_score": 0.0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "listItems",
"query": {
"script": {
"script": "double minVal = 0; minVal = doc['listItems.value'][0]; for (wp in doc['listItems.value']) {if (wp < minVal) { minVal = wp;}} return minVal >= 150 && minVal <= 15000"
}
}
}
}
]
}
}}
Alguém está vendo algo que eu não vejo?
Respostas
A consulta de pesquisa realiza a seguinte agregação:
- Agregação de termos no
idcampo - Agregação mínima em
listItems.value - Agregação Bucket Selector que é uma agregação de pipeline pai que executa um script que determina se o bucket atual será retido na agregação multi-bucket pai.
Adicionar um exemplo funcional com mapeamento de índice, dados de índice, consulta de pesquisa e resultado de pesquisa
Mapeamento de índice:
{
"mappings": {
"properties": {
"listItems": {
"type": "nested"
},
"id":{
"type":"text",
"fielddata":"true"
}
}
}
}
Dados do índice:
{
"id" : "1",
"listItems" :
[
{
"key" : "li1",
"value" : 100
},
{
"key" : "li2",
"value" : 5000
}
]
}
{
"id" : "2",
"listItems" :
[
{
"key" : "li3",
"value" : 200
},
{
"key" : "li2",
"value" : 2000
}
]
}
Consulta de pesquisa:
{
"size": 0,
"aggs": {
"id_terms": {
"terms": {
"field": "id"
},
"aggs": {
"nested_entries": {
"nested": {
"path": "listItems"
},
"aggs": {
"min_position": {
"min": {
"field": "listItems.value"
}
}
}
},
"value_range": {
"bucket_selector": {
"buckets_path": {
"totalValues": "nested_entries>min_position"
},
"script": "params.totalValues >= 150 && params.totalValues < 15000"
}
}
}
}
}
}
Resultado da pesquisa:
"aggregations": {
"id_terms": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "2",
"doc_count": 1,
"nested_entries": {
"doc_count": 2,
"min_position": {
"value": 200.0
}
}
}
]
}
}