비교를 위해 목록의 최소값을 사용하는 ElasticSearch Nested NumericRangeQuery

Sep 25 2020

다음 데이터가 있습니다.

[{
    "id": "1",
    "listItems": [
        {
            "key": "li1",
            "value": 100
        },
        {
            "key": "li2",
            "value": 5000
        }
    ]
},
{
    "id": "2",
    "listItems": [
        {
            "key": "li3",
            "value": 200
        },
        {
            "key": "li2",
            "value": 2000
        }
    ]
}]

각 문서의 listItems에서 MIN 값이 범위 사이에서 일치하도록 NumericRangeQuery 필터를 수행하려고합니다. 예를 들어, 제 범위는 150에서 15000입니다.

내가 이것을 작성하는 방법을 아는 유일한 방법은 스크립트 쿼리를 사용하는 것이지만 코드가 내가 말한 것처럼 MIN을 잡는 대신 범위와 일치 시키려고 시도하는 listItems 아래의 값을 잡는 것처럼 보이기 때문에 작동하지 않는 것 같습니다. 그것으로. 내 질문은 다음과 같습니다.

{
"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"
                        }
                    }
                }
            }
        ]
    }
}}

내가 보지 못하는 것을 본 사람 있나요?

답변

2 ESCoder Sep 26 2020 at 03:23

검색 쿼리는 다음 집계를 수행합니다.

  1. 이용 약관 집계 온 id필드
  2. 최소 집계 에listItems.value
  3. 현재 버킷이 상위 다중 버킷 집계에 유지되는지 여부를 결정하는 스크립트를 실행하는 상위 파이프 라인 집계 인 버킷 선택기 집계 입니다.

인덱스 매핑, 인덱스 데이터, 검색 쿼리 및 검색 결과가 포함 된 작업 예제 추가

인덱스 매핑 :

{
  "mappings": {
    "properties": {
      "listItems": {
        "type": "nested" 
      },
      "id":{
        "type":"text",
        "fielddata":"true"
      }
    }
  }
}

인덱스 데이터 :

{
    "id" : "1",
    "listItems" : 
        [
            {
                "key" : "li1",
                "value" : 100
            },
            {
                "key" : "li2",
                "value" : 5000
            }
        ]
}
{
    "id" : "2",
    "listItems" : 
        [
            {
                "key" : "li3",
                "value" : 200
            },
            {
                "key" : "li2",
                "value" : 2000
            }
        ]
}

검색어:

{
    "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"
                    }
                }
            }
        }
    }
}

검색 결과:

"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
            }
          }
        }
      ]
    }
  }