elasticsearch script_field, sort script

개발새발·2022년 7월 31일
0

elasticsearch

목록 보기
30/54

script 를 사용했을 때, 성능이 어느정도 나오는지 측정하기 위해 script로 ES쿼리문을 짜봐야했다. 처음에는 계산한 값을 통한 정렬때문에 script를 생각했으나, 필드자체에도 script로 계산한 필드값이 들어가야했다.

1. Script_field

  • 사용방법
GET /{index명}/_search

{
  "script_fields": {
    "{만들 필드명}: {
      "script": { 
        "source": "{해당 필드에 넣을 값 또는 계산식}", 
        "params": { // 필요하다면 해당 params로 source 계산에 사용할 수 있다.
          "{파라메타}": {파라메타값}
        }
      }
    }
  }
}
  • 사용예시

아래 조건을 간단히 설명하자면, total_price 라는 필드를 script를 사용하여 만든다. doc[’apple’] 은 필드를 의미한다. 때문에 doc['apple'].size()==0 은 필드가 존재하는 지 체크하여 존재하지 않는다면 0으로 처리하고, 존재한다면 doc['apple'].value 필드값으로 처리한다. params.apple_price는 아래에 params로 정의해준 값을 뜻한다.

GET /test/_search

{
  "script_fields": {
    "total_price": {
      "script": {
        "source": "(doc['apple'].size()==0 ? 0 : doc['apple'].value) * params.apple_price + (doc['pear'].size()==0 ? 0 :doc['pear'].value) * params.pear_price",
        "params": {
          "apple_price": 1000,
          "pear_price": 5000
        }
      }
    }
  },
  "_source": [
    "applce_price",
    "pear_price",
  ],
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "_index": [
              "test"
            ]
          }
        }
      ],
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "selling": true
              }
            }
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 10,
  "sort": {
    "price" : "asc"
  }
}

⚠️주의⚠️

그럼 script_field 로 ES쿼리문을 짜면, script를 통해 만들어진 필드로 소팅도 할 수 있을까? 했는데 으림없지^^.. 아래와 같은 에러가 떴다. (가능한 방법이 있으면 댓글 부탁드립니다!! 🥲) 그래서 사용해야겠구만.. 한게 sort script였다.

"reason": {
  "type": "query_shard_exception",
  "reason": "No mapping found for ["total_price"] in order to sort on",
  "index_uuid": "2z4nzxlSSQ6XuELzONy5ZA",
  "index": "{index명}"
}

2. Sort Script

  • 사용방법
GET /{인덱스명}/_search

{
  "query": {
    "term": { "{필드명}": "{필드조건}" }
  },
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "source": "{sort조건}",
        "params": {
          "{파라미터}": {파라미터값}
        }
      },
      "order": "{asc or desc}"
    }
  }
}
  • 사용예시
GET /test/_search

{
  "_source": [
    "apple_price",
		"pear_price"
    "updated_date"
  ],
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "_index": [
              "test"
            ]
          }
        }
      ],
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "selling": true
              }
            }
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 10,
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "source": "(doc['apple'].size()==0 ? 0 : doc['apple'].value) * params.apple_price + (doc['pear'].size()==0 ? 0 :doc['pear'].value) * params.pear_price",
        "params": {
          "apple_price": 1000,
          "pear_price": 5000
        }
      },
      "order": "asc"
    }
  }
}
profile
발새발개

0개의 댓글