elasticsearch painless 스크립트

14796 단어 elasticsearch
출처:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/modules-scripting-fields.html#_search_and_aggregation_scripts https://www.elastic.co/guide/en/elasticsearch/painless/6.5/painless-examples.html앞부분은es버전5.5,script중은inline필드,뒷부분은es버전6.5,script중은source필드

스크립트


언어
샌드박스
필요한 플러그인
painless
yes
내장
groovy
no
내장
javascript
no
lang-javascript
python
no
lang-javascript
언어
샌드박스
필요한 플러그인
본고는 painless와 JavaAPI만 소개합니다.

문법 모드

 "script": {
 	"lang": "...", (1)
	"inline" | "stored" | "file": "...", (2)
	"params": { ... } (3)
}

(1) 스크립트를 쓰는 언어, 기본값은painless입니다.(2) 스크립트는 inline,stored,or 파일로 지정할 수 있습니다.(3) 스크립트에 전달되는 이름 매개 변수.
단순 인스턴스 테스트:
PUT my_index/my_type/1
{
	"my_field": 5
}

GET my_index/_search
{
  "script_fields": {
    "my_doubled_field": {
      "script": {
        "lang": "expression",
        "inline": "doc['my_field'] * multiplier",
        "params": {
          "multiplier": 2
        }
      }
    }
  }
}
// 
{
  "took": 176,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1.0,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 1.0,
        "fields": {
          "my_doubled_field": [
            10.0
          ]
        }
      }
    ]
  }
}

매개 변수


lang


스크립트에 쓸 언어를 지정합니다. 모든 스크립트 언어를 설정할 수 있습니다.config 파일에서 elasticsearch를 변경할 수 있습니다.yml를 script로 설정합니다.default_언어

inline, stored, file


스크립트의 원본 inline 스크립트를 지정합니다. 위eg에서 보듯이stored는 그룹에 저장되고 (see Stored Scripts 초연결) config/scripts 디렉터리에서 파일 스크립트를 검색합니다. (파일 스크립트 참조)많은 표현식과painless 언어는 인라인이나 저장된 스크립트 설정으로 사용할 수 있지만, 기본 스크립트 보안 설정을 먼저 조정하지 않으면groovy 같은 다른 언어는 파일로만 지정될 수 있습니다.

params


변수로 스크립트에 전달되는 모든 이름 매개 변수 지정ps: 변수를 스크립트에 전달해야 한다면, 스크립트 자체의 인코딩으로 변환하지 않고 이름 매개 변수로 전달해야 합니다.
// !!!!!
"inline": "doc['my_field'] * 2"
// :
"inline": "doc['my_field'] * multiplier",
"params": {
"multiplier": 2
}

스크립트 스토리지


스크립트는 _scripts 종점은 집단 상태에 저장되어 집단 상태에서 검색됩니다.

자동 스크립트 재부팅


스크립트 디렉터리는 60초마다 다시 스캔합니다. (resource.reload.interval 설정을 사용하여 설정할 수 있습니다.) 새 스크립트, 변경되거나 삭제된 스크립트는 스크립트 캐시에서 컴파일, 업데이트 또는 삭제됩니다.스크립트를 다시 불러오면 스크립트를 사용할 수 있습니다.auto_reload_enabled는false로 설정하여 완전히 비활성화합니다.

버려진 이름 공간


lang과 id를 유일한 식별자로 사용하는 저장 스크립트의 이름 공간이 사용되지 않습니다.스크립트를 저장하는 새 이름 공간은 id만 사용할 수 있습니다.저장된 스크립트는 같은 id를 가지고 있지만, 다른lang은 6.0에서 허용되지 않습니다.스크립트를 저장하는 새로운 명칭 공간을 준수하려면 기존 저장된 스크립트를 삭제하고 다시 놓아야 합니다.공유 id지만 서로 다른 "lang"스크립트는 이름을 바꾸어야 합니다.예를 들어 "id": "example", "lang": "painless", "id": "example", "lang": "표현식"상기 스크립트는 id가 같기 때문에 새로운 이름 공간에서 충돌합니다.적어도 이름이 바뀌어야 id를 준수할 수 있는 새로운 이름 공간이 있습니다.마지막 주의사항으로 저장된 검색 템플릿과 저장된 스크립트는 같은 명칭 공간을 공유하기 때문에 검색 템플릿이 저장된 스크립트와 같은 표지를 가지고 있다면delete와put를 사용하여 그 중 하나를 다시 이름을 지정해야 합니다.
/_scripts/{id}
 :id 

// calculate-score  painless  :
POST _scripts/calculate-score
{
    "script": {
    "lang": "painless",
    "code": "Math.log(_score * 2) + params.my_modifier"
    }
}
// 
GET _scripts/calculate-score
// 
DELETE _scripts/calculate-score

쿼리 집합 스크립트


모든 검색에서 한 번 실행되는 스크립트 필드를 제외하고, 검색과 집합에 사용되는 스크립트는 검색이나 집합과 일치할 수 있는 모든 문서에 한 번 실행됩니다.당신이 얼마나 많은 파일을 가지고 있는지에 따라 수백만 또는 수십억 위안의 실행을 의미할 수 있습니다. 이 스크립트들은 빨라야 합니다!문서 값 또는 저장된 필드 또는 _소스 필드는 스크립트에서 필드 값에 접근합니다. 이 위치는 다음과 같습니다.스크립트는 또한 문서의 상관성에 액세스할 수 있습니다_score, 그리고 실험을 통해_index 변수는 고급 텍스트 평점의 용어 통계 정보에 접근합니다.score 문서에 접근하는 스크립트는function_score 조회, 스크립트의 정렬 또는 집합에 사용되는 스크립트를 바탕으로 문서의 현재 관련성 점수를 나타내는 _score 변수.다음은 function_score 쿼리의 스크립트가 각 문서의 관련성을 변경합니다_score의 예:
PUT my_index/my_type/1
{
  "text": "quick brown fox",
  "popularity": 1
}

PUT my_index/my_type/2
{
  "text": "quick fox",
  "popularity": 5
}

GET my_index/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "text": "quick brown fox"
        }
      },
      "script_score": {
        "script": {
          "lang": "expression",
          "inline": "_score * doc['popularity']"
        }
      }
    }
  }
}

다음은 자신이 번역한 것입니다. 문제가 있으면 바로잡아 주십시오!

doc 값 및 텍스트 필드(Doc values and text fields)


The doc ['field'] syntax can also be used for analyzed text fields if fielddata is enabled, doc ['field'] 이런 문법 역시 fielddata가 허용하는 상황에서 분석 텍스트 필드에 사용할 수 있다
but BEWARE: enabling fielddata on a text field requires loading all of the terms into the JVM heap, which can be very expensive both in terms of memory and CPU. It seldom makes sense to access text fields from scripts. 그러나 주의: fielddata가 text 필드에서 모든 항목을 JVM 더미에 불러오는 것을 허용하면 대량의 cpu와 메모리가 소모됩니다.그래서 스크립트에서 텍스트 필드를 거의 얻지 못하는 것은 일리가 있다

스토리지 필드 및_source


Stored fields — fields explicitly marked as “store”: true — can be accessed using the_fields[‘field_name’].value or _fields[‘field_name’].values syntax. 저장 필드 - "store"표시가 명확한: true 필드 - - 사용 가능_fields[‘field_name’].value 또는_fields[‘field_name’].values 같은 문법으로 필드의 값을 가져옵니다.
The document _source, which is really just a special stored field, can be accessed using the _source.field_name syntax. The _source is loaded as a map-of-maps, so properties within object fields can be accessed as, for example, _source.name.first. 문서의_source는 특수한 저장 필드일 뿐입니다. _source.field_name에서 사용,_소스는 맵-of-maps로 불러오기 때문에 대상 필드의 내용은 다음 형식으로 얻을 수 있습니다:_source.name.first
ps:Prefer doc-values to stored fields 저장 필드가 아닌 doc-values를 사용하는 경향이 있음
They are optimised for returning several fields per result, while doc values are optimised for accessing the value of a specific field in many documents. 저장 필드 최적화는 모든 결과의 몇 개의 필드를 되돌려주는 데 사용되며,docvalues 최적화는 여러 문서에 있는 특정한 필드를 가져오는 데 사용됩니다.
It makes sense to use _source or stored fields when generating a script field for the top ten hits from a search result but, for other search and aggregation use cases, always prefer using doc values. 스크립트 필드를 생성하여 가장 좋은 10을 명중시키면 사용_소스나 저장 필드는 모두 가능하지만 다른 검색과 집합 사용 사례에 대해서는 항상 doc-values를 사용하는 경향이 있다
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "title": { // 1、 stored _fields[] 
          "type": "text"
        },
        "first_name": {
          "type": "text",
          "store": true
        },
        "last_name": {
          "type": "text",
          "store": true
        }
      }
    }
  }
}

PUT my_index/_doc/1?refresh
{
  "title": "Mr",
  "first_name": "Barry",
  "last_name": "White"
}

GET my_index/_search
{
  "script_fields": {
    "source": {
      "script": {
        "lang": "painless",
        //title _source 
        "source": "params._source.title + ' ' + params._source.first_name + ' ' + params._source.last_name" 
      }
    },
    "stored_fields": {
      "script": {
        "lang": "painless",
        "source": "params._fields['first_name'].value + ' ' + params._fields['last_name'].value"
      }
    }
  }
}

tip:Stored vs _source The _source field is just a special stored field, so the performance is similar to that of other stored fields. _소스 필드는 특수한 저장 필드일 뿐이기 때문에 다른 저장 필드와 매우 비슷하다.
The _source provides access to the original document body that was indexed (including the ability to distinguish null values from empty fields, single-value arrays from plain scalars, etc). _소스 필드는 인덱스된 원시 파일체를 가져오는 방법을 제공합니다. (빈 필드, 단일 값 그룹에서null 값을 구별할 수 있는 능력 등)
The only time it really makes sense to use stored fields instead of the _source field is when the _source is very large and it is less costly to access a few small stored fields instead of the entire _source. 스토리지 필드를 대체할 수 있는 유일한 가치 _source 필드는 _소스가 매우 크고 전체 _ 대신 소량의 저장 필드를 가져옵니다소스 이런 게 더 싸요.

간단한 스크립트

// 
"script": "ctx._source.likes++"
// 
"script": {
    "source": "ctx._source.likes++"
}

스크립트 전환 시간 예
// 
{
  "size": 1, 
  "script_fields": {
    "birth_year": {
      "script": {
        "inline": "DateTimeFormatter dtf = DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss');LocalDateTime ldt1 =LocalDateTime.parse(doc['public_data'].value,dtf);LocalDateTime ldt2 = LocalDateTime.parse(doc['create_data'].value,dtf);return Duration.between(ldt1,ldt2).toDays(); "
      }
    }
  }
}

//filter   
GET evening/_search
{
    "query": {
        "bool" : {
            "filter" : {
                "script" : {
                    "script" : {
                        "source" : "doc['sold'].value == false && doc['cost'].value < params.cost",
                        "params" : {
                            "cost" : 18
                        }
                    }
                }
            }
        }
    }
}

Java 스크립트 집합:
        Script allWeightScript = new Script(ScriptType.INLINE, "painless",
                "Integer.parseInt(doc['meterage_weight'].value)",// meterage_weight ( keyword) int
                Collections.emptyMap());

        AggregationBuilder allWeightAgg = AggregationBuilders.filter("allTicket", QueryBuilders.rangeQuery("meterage_weight").from("0")).subAggregation(
                AggregationBuilders.sum("allWeight").script(allWeightScript)
        );

        Script weightUp20KGScript = new Script(ScriptType.INLINE, "painless",
                "int weight = Integer.parseInt(doc['meterage_weight'].value);if(weight>=20){return weight;}else{return 0;}",// 20 meterage_weight
                Collections.emptyMap());

		AggregationBuilder weightUp20KGAgg = AggregationBuilders.filter("up20KGTicket", QueryBuilders.rangeQuery("meterage_weight").from("20"))
                .subAggregation(AggregationBuilders.sum("up20KGWeight").script(allWeightScript));

좋은 웹페이지 즐겨찾기