Transforms APIs
출처: 문서
본문
Transform API
OpenSearch Dashboards를 사용하는 것 외에도, REST API를 사용해서 transform job을 생성, 시작, 중지하는 등 관련 작업을 수행할 수 있어요.
이 페이지의 예제는 OpenSearch Dashboards 샘플 e-commerce 데이터를 사용해요. 추가하려면 OpenSearch Dashboards 홈 페이지로 가서 Try our sample data를 선택하고, Sample eCommerce orders에서 Add data를 선택하세요.
목차
- TOC {:toc}
Transform job 생성하기
1.0에서 도입 {: .label .label-purple }
transform job을 생성해요.
엔드포인트
PUT _plugins/_transform/{transform_id}
경로 파라미터
| 파라미터 | 데이터 타입 | 설명 |
|---|---|---|
transform_id |
String | transform ID |
요청 본문 필드
HTTP 요청 본문에서 다음 옵션들을 지정할 수 있어요:
| 옵션 | 데이터 타입 | 설명 | 필수 여부 |
|---|---|---|---|
enabled |
Boolean | 생성 시점에 transform job의 활성화 여부예요. 기본값은 true예요. |
아니요 |
continuous |
Boolean | transform job을 연속(continuous)으로 실행할지 여부를 지정해요. 연속 job은 schedule 필드에 따라 실행될 때마다 수행되며, 새로 변환된 bucket과 source 인덱스에 추가된 새 데이터를 기반으로 동작해요. 비연속 job은 한 번만 실행돼요. 기본값은 false예요. |
아니요 |
schedule |
Object | transform job의 실행 일정이에요. period, unit, start_time 필드를 가진 interval 객체를 포함해요. |
예 |
description |
String | transform job을 설명해요. | 예 |
source_index |
String | 변환할 데이터를 담고 있는 source 인덱스예요. | 예 |
target_index |
String | 새로 변환된 데이터가 추가될 target 인덱스예요. 새 인덱스를 만들거나 기존 인덱스를 업데이트할 수 있어요. | 예 |
data_selection_query |
Object | transform job에서 source 인덱스의 일부를 필터링할 때 사용할 query DSL이에요. 이 필드를 생략하면 job이 source 인덱스의 모든 문서를 변환해요. 자세한 내용은 Query DSL을 참고하세요. | 아니요 |
page_size |
Integer | IM이 동시에 처리하고 인덱싱하는 bucket 수예요. 값이 클수록 성능은 좋아지지만 더 많은 메모리가 필요해요. 머신의 메모리가 부족해지면 Index Management(IM)가 이 필드를 자동으로 조정하고 작업이 성공할 때까지 재시도해요. | 예 |
groups |
Array | transform job에서 사용할 grouping을 지정해요. 각 항목은 source 인덱스의 source_field와 그 값을 쓸 target_field를 지정해요. 지원되는 group은 terms, histogram, date_histogram이에요. job은 최소 하나의 group을 정의해야 해요. 자세한 내용은 Bucket aggregations을 참고하세요. |
예 |
aggregations |
Object | transform job에서 사용할 aggregation이에요. 지원되는 aggregation은 sum, max, min, value_count, avg, scripted_metric, percentiles예요. 자세한 내용은 Metric aggregations을 참고하세요. |
아니요 |
예제 요청
다음 요청은 id가 sample인 transform job을 생성해요:
PUT _plugins/_transform/sample
{
"transform": {
"enabled": true,
"continuous": true,
"schedule": {
"interval": {
"period": 1,
"unit": "Minutes",
"start_time": 1602100553
}
},
"description": "Sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"target_index": "ecommerce_transform",
"data_selection_query": {
"match_all": {}
},
"page_size": 1,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
}
}
}
{% include copy-curl.html %}
예제 응답
{
"_id": "sample",
"_version": 1,
"_seq_no": 13,
"_primary_term": 1,
"transform": {
"transform_id": "sample",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1602100553,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": null,
"updated_at": 1621467964243,
"enabled": true,
"enabled_at": 1621467964243,
"description": "Sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform",
"page_size": 1,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": true
}
}
metadata_id 필드는 OpenSearch가 할당하는 값으로, job이 처음 실행되기 전까지는 null이에요. 요청에서 이 값을 설정해도 효과가 없어요.
{: .note}
Transform job 업데이트하기
1.0에서 도입 {: .label .label-purple }
transform_id가 이미 존재하면 transform job을 업데이트해요. 이 요청에서는 업데이트할 transform의 sequence number와 primary term을 반드시 지정해야 해요. 이 값들을 얻으려면 Transform job 상세 조회하기 API를 사용하세요.
엔드포인트
PUT _plugins/_transform/{transform_id}?if_seq_no={seq_no}&if_primary_term={primary_term}
쿼리 파라미터
업데이트 작업은 다음 쿼리 파라미터를 지원해요:
| 파라미터 | 설명 | 필수 여부 |
|---|---|---|
if_seq_no |
transform job을 마지막으로 변경한 작업이 지정된 sequence number와 일치할 때만 transform 작업을 수행해요. | 예 |
if_primary_term |
transform job을 마지막으로 변경한 작업이 지정된 sequence term과 일치할 때만 transform 작업을 수행해요. | 예 |
요청 본문 필드
요청 본문에 transform 객체 전체를 담아 보내야 해요. 변경할 수 있는 필드는 다음뿐이에요.
| 옵션 | 데이터 타입 | 설명 |
|---|---|---|
enabled |
Boolean | transform job의 활성화 여부예요. |
schedule |
Object | transform job의 실행 일정이에요. interval.start_time, interval.period, interval.unit 필드를 포함해요. |
interval.start_time |
Integer | transform job의 Unix epoch 시작 시간이에요. |
interval.period |
Integer | transform job을 실행하는 주기예요. |
interval.unit |
String | 실행 주기의 시간 단위예요. 사용 가능한 옵션은 Minutes, Hours, Days예요. |
description |
String | transform job을 설명해요. |
page_size |
Integer | IM이 동시에 처리하고 인덱싱하는 bucket 수예요. 값이 클수록 성능은 좋아지지만 더 많은 메모리가 필요해요. 머신의 메모리가 부족해지면 IM이 이 필드를 자동으로 조정하고 작업이 성공할 때까지 재시도해요. |
나머지 필드들은 job이 이미 가진 값으로 그대로 채워 넣어야 해요. continuous, source_index, target_index, data_selection_query, groups, aggregations를 변경하면 400으로 거부되고, 이 중 하나라도 생략하면 변경으로 간주돼요. 예를 들어 "continuous": true로 생성된 job의 요청 본문에서 continuous를 빼먹으면 실패해요.
{: .note}
예제 요청
다음 요청은 id가 sample이고 sequence number가 13, primary term이 1인 transform job을 업데이트해요:
PUT _plugins/_transform/sample?if_seq_no=13&if_primary_term=1
{
"transform": {
"enabled": true,
"continuous": true,
"schedule": {
"interval": {
"period": 1,
"unit": "Minutes",
"start_time": 1602100553
}
},
"description": "Updated sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"target_index": "ecommerce_transform",
"data_selection_query": {
"match_all": {}
},
"page_size": 10,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
}
}
}
{% include copy-curl.html %}
예제 응답
{
"_id": "sample",
"_version": 2,
"_seq_no": 14,
"_primary_term": 1,
"transform": {
"transform_id": "sample",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1602100553,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": null,
"updated_at": 1621467999831,
"enabled": true,
"enabled_at": 1621467999830,
"description": "Updated sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform",
"page_size": 10,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": true
}
}
Transform job 상세 조회하기
1.0에서 도입 {: .label .label-purple }
transform job의 상세 정보를 반환해요.
엔드포인트
GET _plugins/_transform/{transform_id}
예제 요청
다음 요청은 id가 sample인 transform job의 상세 정보를 반환해요:
GET _plugins/_transform/sample
{% include copy-curl.html %}
예제 응답
{
"_id": "sample",
"_version": 3,
"_seq_no": 15,
"_primary_term": 1,
"transform": {
"transform_id": "sample",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1602100553,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": "cAgQ_8RVFy4ZoSZb0g4XNw",
"updated_at": 1621468022451,
"enabled": true,
"enabled_at": 1621467999830,
"description": "Updated sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform",
"page_size": 10,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": true
}
}
transform_id를 생략하면 모든 transform job의 상세 정보를 가져올 수도 있어요.
예제 요청
다음 요청은 모든 transform job의 상세 정보를 반환해요:
GET _plugins/_transform/
{% include copy-curl.html %}
예제 응답
{
"total_transforms": 1,
"transforms": [
{
"_id": "sample",
"_seq_no": 15,
"_primary_term": 1,
"transform": {
"transform_id": "sample",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1602100553,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": "cAgQ_8RVFy4ZoSZb0g4XNw",
"updated_at": 1621468022451,
"enabled": true,
"enabled_at": 1621467999830,
"description": "Updated sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform",
"page_size": 10,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": true
}
}
]
}
각 항목에는 _version이 빠져 있는데, 이 필드는 단일 transform job을 요청할 때만 응답에 포함돼요.
쿼리 파라미터
결과를 필터링하려면 GET API 작업에서 다음 쿼리 파라미터를 지정할 수 있어요.
| 파라미터 | 설명 | 필수 여부 |
|---|---|---|
from |
반환을 시작할 transform의 위치예요. 기본값은 0이에요. | 아니요 |
size |
반환할 transform의 개수를 지정해요. 기본값은 10이에요. | 아니요 |
search |
결과를 필터링할 때 사용할 검색어예요. | 아니요 |
sortField |
결과를 정렬할 기준 필드예요. 저장된 transform 문서로 들어가는 경로 형태로 지정하며, 예를 들어 transform.transform_id.keyword나 transform.updated_at 같은 값이에요. transform_id처럼 매핑되지 않은 이름은 500으로 거부돼요. |
아니요 |
sortDirection |
결과를 정렬할 방향을 지정해요. ASC 또는 DESC를 사용할 수 있어요. 기본값은 ASC예요. |
아니요 |
예제 요청
다음 요청은 transform 8부터 시작해서 transform ID 기준으로 정렬된 두 개의 결과를 반환해요:
GET _plugins/_transform?size=2&from=8&sortField=transform.transform_id.keyword
{% include copy-curl.html %}
예제 응답
{
"total_transforms": 18,
"transforms": [
{
"_id": "sample8",
"_seq_no": 93,
"_primary_term": 1,
"transform": {
"transform_id": "sample8",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1622063596812,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": "y4hFAB2ZURQ2dzY7BAMxWA",
"updated_at": 1622063657233,
"enabled": false,
"enabled_at": null,
"description": "Sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform8",
"page_size": 1,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": false
}
},
{
"_id": "sample9",
"_seq_no": 98,
"_primary_term": 1,
"transform": {
"transform_id": "sample9",
"schema_version": 30,
"schedule": {
"interval": {
"start_time": 1622063598065,
"period": 1,
"unit": "Minutes"
}
},
"metadata_id": "x8tCIiYMTE3veSbIJkit5A",
"updated_at": 1622063658388,
"enabled": false,
"enabled_at": null,
"description": "Sample transform job",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"data_selection_query": {
"match_all": {
"boost": 1.0
}
},
"target_index": "ecommerce_transform9",
"page_size": 1,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
},
"continuous": false
}
}
]
}
Transform job 시작하기
1.0에서 도입 {: .label .label-purple }
API로 생성한 transform job은 자동으로 활성화되지만, job을 활성화할 필요가 생기면 start API 작업을 사용할 수 있어요.
엔드포인트
POST _plugins/_transform/{transform_id}/_start
예제 요청
다음 요청은 ID가 sample인 transform job을 시작해요:
POST _plugins/_transform/sample/_start
{% include copy-curl.html %}
예제 응답
{
"acknowledged": true
}
Transform job 중지하기
1.0에서 도입 {: .label .label-purple }
transform job을 중지해요.
엔드포인트
POST _plugins/_transform/{transform_id}/_stop
예제 요청
다음 요청은 ID가 sample인 transform job을 중지해요:
POST _plugins/_transform/sample/_stop
{% include copy-curl.html %}
예제 응답
{
"acknowledged": true
}
Transform job 상태 조회하기
1.0에서 도입 {: .label .label-purple }
transform job의 상태와 메타데이터를 반환해요.
엔드포인트
GET _plugins/_transform/{transform_id}/_explain
예제 요청
다음 요청은 ID가 sample인 transform job의 상세 정보를 반환해요:
GET _plugins/_transform/sample/_explain
{% include copy-curl.html %}
예제 응답
{
"sample": {
"metadata_id": "cAgQ_8RVFy4ZoSZb0g4XNw",
"transform_metadata": {
"transform_id": "sample",
"last_updated_at": 1621883525873,
"status": "started",
"failure_reason": null,
"stats": {
"pages_processed": 3,
"documents_processed": 4675,
"documents_indexed": 14,
"index_time_in_millis": 22,
"search_time_in_millis": 88
},
"continuous_stats": {
"last_timestamp": 1621883525672,
"documents_behind": {
"opensearch_dashboards_sample_data_ecommerce": 0
}
}
}
}
}
status 필드는 job이 실행 중일 때는 started, 연속(continuous)이 아닌 job이 완료되면 finished, 중지하면 stopped, 실패하면 failed가 돼요. 실패한 경우 failure_reason에 Failed to index the documents 같은 메시지가 담겨요. continuous_stats 객체는 연속(continuous) job에만 존재하며, 이때 documents_behind는 job이 아직 변환하지 못한 source 문서 수를 세어요.
metadata_id와 transform_metadata는 모두 job이 처음 실행되기 전까지는 null이에요.
{: .note}
Transform job 결과 미리 보기
1.0에서 도입 {: .label .label-purple }
변환된 인덱스가 어떤 모습이 될지 미리 보여주는 preview를 반환해요. preview는 job을 생성하지 않고 target 인덱스에도 쓰지 않아요.
엔드포인트
POST _plugins/_transform/_preview
예제 요청
POST _plugins/_transform/_preview
{
"transform": {
"enabled": false,
"schedule": {
"interval": {
"period": 1,
"unit": "Minutes",
"start_time": 1602100553
}
},
"description": "test transform",
"source_index": "opensearch_dashboards_sample_data_ecommerce",
"target_index": "ecommerce_transform",
"data_selection_query": {
"match_all": {}
},
"page_size": 10,
"groups": [
{
"terms": {
"source_field": "customer_gender",
"target_field": "gender"
}
},
{
"terms": {
"source_field": "day_of_week",
"target_field": "day"
}
}
],
"aggregations": {
"quantity": {
"sum": {
"field": "total_quantity"
}
}
}
}
}
{% include copy-curl.html %}
예제 응답
각 문서는 group화된 필드와 aggregation 값, 그리고 bucket 안의 source 문서 수를 담고 있으며, 이 문서 수는 _doc_count와 transform._doc_count 양쪽에 모두 표시돼요:
{
"documents" : [
{
"_doc_count" : 399,
"quantity" : 862.0,
"gender" : "FEMALE",
"transform._doc_count" : 399,
"day" : "Friday"
},
{
"_doc_count" : 320,
"quantity" : 682.0,
"gender" : "FEMALE",
"transform._doc_count" : 320,
"day" : "Monday"
},
{
"_doc_count" : 365,
"quantity" : 772.0,
"gender" : "FEMALE",
"transform._doc_count" : 365,
"day" : "Saturday"
},
{
"_doc_count" : 315,
"quantity" : 669.0,
"gender" : "FEMALE",
"transform._doc_count" : 315,
"day" : "Sunday"
},
{
"_doc_count" : 417,
"quantity" : 887.0,
"gender" : "FEMALE",
"transform._doc_count" : 417,
"day" : "Thursday"
},
{
"_doc_count" : 323,
"quantity" : 690.0,
"gender" : "FEMALE",
"transform._doc_count" : 323,
"day" : "Tuesday"
},
{
"_doc_count" : 294,
"quantity" : 612.0,
"gender" : "FEMALE",
"transform._doc_count" : 294,
"day" : "Wednesday"
},
{
"_doc_count" : 371,
"quantity" : 821.0,
"gender" : "MALE",
"transform._doc_count" : 371,
"day" : "Friday"
},
{
"_doc_count" : 259,
"quantity" : 586.0,
"gender" : "MALE",
"transform._doc_count" : 259,
"day" : "Monday"
},
{
"_doc_count" : 371,
"quantity" : 798.0,
"gender" : "MALE",
"transform._doc_count" : 371,
"day" : "Saturday"
}
]
}
preview는 최대 page_size개의 문서만 반환하므로, 나머지 bucket을 보려면 page_size를 늘리면 돼요.
{: .note}
Transform job 삭제하기
1.0에서 도입 {: .label .label-purple }
transform job을 삭제해요. 이 작업은 source나 target 인덱스를 삭제하지 않아요.
활성화된 job은 삭제할 수 없어요. 먼저 job을 중지하거나, force를 true로 설정해서 아직 활성화된 상태에서 삭제할 수 있어요.
엔드포인트
DELETE _plugins/_transform/{transform_id}
쿼리 파라미터
| 파라미터 | 설명 | 필수 여부 |
|---|---|---|
force |
활성화 상태라도 transform job을 삭제해요. 기본값은 false예요. |
아니요 |
예제 요청
다음 요청은 ID가 sample인 transform job을 삭제해요:
DELETE _plugins/_transform/sample
{% include copy-curl.html %}
예제 응답
{
"took": 205,
"errors": false,
"items": [
{
"delete": {
"_index": ".opendistro-ism-config",
"_id": "sample",
"_version": 4,
"result": "deleted",
"forced_refresh": true,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 1,
"status": 200
}
}
]
}
아직 활성화된 상태인 job을 삭제하려고 하면 409로 실패해요. 존재하지 않는 job을 삭제하면 200이 반환되고, 항목 안에 "result": "not_found"와 "status": 404가 담겨요.
{: .note}