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