'Document API'에 해당되는 글 8건
08. Update API :: 2015/05/20 13:07
Update API는 제공된 script에 따라 document를 업데이트한다. Operation은 index로부터 document를 조회하고 script를 실행하여 그 결과를 index에 저장한다. 물론 조회나 reindex하는 과정에서 업데이트가 없다는 것은 버전으로 확인할 수 있다.
이 operation은 document의 full reindex를 의미하며, network roundtrip을 제거하고 get operation과 index사이에 버전 변경으로 인한 충돌을 감소시켜야 함에 유의하라. 이러한 특징을 해결하기 위해서 _source field가 필요하다.
예를 들어 다음 간단한 document를 index해보자.
curl -XPUT
localhost:9200/test/type1/1 -d '{
"counter" : 1,
"tags" : ["red"]
}'
이제 counter를 증가시키는 script를 실행할 수 있다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
}
}'
또한 태그 리스트에 태그를 추가할 수도 있다. (만약 태그가 존재하더라도 리스트이기 때문에 추가된다.)
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.tags += tag",
"params" : {
"tag" : "blue"
}
}'
Document에 새로운 field도 추가할 수 있다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.name_of_new_field =
\"value_of_new_field\""
}'
Document로부터 field를 삭제할 수도 있다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.remove(\"name_of_field\")"
}'
태그가 blue인 document를 삭제하거나, blue가 아닐 경우 삭제하지 않을 수도 있다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.tags.contains(tag) ? ctx.op =
\"delete\" : ctx.op = \"none\"",
"params" : {
"tag" : "blue"
}
}'
[NOTE]
3진 operator와 assignment를 다루는 것을 알아야 한다. Assignment operation은 3진 operator에 비해서 우선순위가 낮다. 다음 항목들을 비교해 보자.
// Will NOT update
the tags array
ctx._source.tags.contains(tag) ? ctx.op = \"none\" : ctx._source.tags += tag
//
Will update
ctx._source.tags.contains(tag) ? (ctx.op = \"none\") : ctx._source.tags += tag
//
Also works
if (ctx._source.tags.contains(tag)) { ctx.op = \"none\" } else { ctx._source.tags += tag }
Update API를 통해서 또한 document의 일부분만 전송할 수 있다. 전송된 내용은 이미 존재하는 document에 merge된다. (간단히 말하자면 recursive merge, object의 inner merge, "key/value" array를 replace하는 것이다.)
예를 들면 다음과 같다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"doc" : {
"name" : "new_name"
}
}'
Doc과 script를 지정하면 doc은 무시된다. Script내에 document의 일부분에 해당하는 field pair를 넣는 것이 가장 좋다. 기본적으로 doc이 지정되면, document는 merge process가 어떤 변화를 일으키지 않더라도 항상 update된다. Detect_noop을 true로 설정하면 Elasticsearch에서 변경사항이 있는지를 체크하고 아니면 update request가 noop이 된다. 예를 들면 다음과 같다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"doc" : {
"name" : "new_name"
},
"detect_noop": true
}'
Request가 보내지기 전에 name이 new_name이라면 전체 update request는 무시한다.
Upserts
Elasticsearch Update API에는 upsert도 있다. Document가 이미 존재하지 않으면, upsert element의 content는 새로운 document로 index될 것이다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
},
"upsert" : {
"counter" : 1
}
}'
Document가 없으면 스크립트를 통해서 client에는 알려지지 않은 business logic을 사용하여 document content를 초기화하도록 할 수 있다. 이런 경우에는 새로운 scripted_upsert parameter를 true로 설정하면 된다.
curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update' -d '{
"script_id" : "my_web_session_summariser",
"scripted_upsert":true,
"params" : {
"pageViewEvent" : {
"url":"foo.com/bar",
"response":404,
"time":"2014-01-01 12:32"
}
},
"upsert" : {
}
}'
Default scripted_upsert 설정은 false이다. 이것은 script가 insert를 위해서는 실행되지 않음을 의미한다. 그러나 위와 같은 시나리오에서처럼 새로운 "indexed scripts" feature를 이용하여 저장된 중요한 (non-trivial) script를 사용할 수 있다. 스크립트를 통해서 여러 page view event에 기반한 web session의 기간 (duration)과 같은 특징들을 뽑아낼 수도 있다. Client에서는 blank "upsert" document를 제공하거나 params element로 넘겨진 event를 사용하여 최대한 상세하게 채워서 script를 실행할 수도 있다.
마지막으로 upsert 기능은 doc_as_upsert도 지원한다. 제공된 document는 기존에 존재하지 않는 document일 경우에 insert된다. 이것은 Elasticsearch로 전송되는 데이터의 양을 감소시킬 것이다.
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"doc" : {
"name" : "new_name"
},
"doc_as_upsert" : true
}'
Parameters
Update operation은 index API처럼 유사한 parameter를 지원한다.
Routing : document를 적합한 shard로 route하는데 사용하는 설정
Parent : routing의 단순 설정
Timeout : shard가 다시 사용가능해질 때까지 기다리는 시간
Replication : delete/index operation (sync, async)에 대한 replication type. 1.5.0에서 deprecated.
Consistency : index/delete operation의 write consistency
Refresh : 전체 index가 아니라 적합한 primary와 replica shard를 operation이 발생한 이후 즉시 refresh. 따라서, update document가 바로 검색 결과로 나타난다.
Fields : update된 document로부터 적합한 fields를 리턴. 전체 update된 source를 리턴하기 위해서 _source를 지원.
Version & version_type : Update API는 Elasticsearch 내부에서 지원하는 versioning을 사용함. Update되는 동안 document가 변경되지 않았음을 version으로 판별. 특정 version의 document를 update하기 위해서 version parameter를 사용할 수도 있음. Version type을 force로 설정하면 강제로 document를 update하고 새로운 version이 부여됨. (사용하는데 주의할 것! Force를 사용하면 document가 변경되지 않았음을 보증할 수 없음.) external & external_gte version type은 지원되지 않음
조회한 document와 그것을 indexing / deleting하는 사이에 version 충돌이 발생하면 몇번이나 retry해야 하는지를 설정하는 Retry_on_conflict 를 지원한다. Default는 0이다.
또한 ctx._ttl을 사용하여 document의 ttl을 update할 수 있다. 그리고 ctx._timestamp를 사용하여 document의 timestamp를 update할 수 있다. 만약 timestamp가 update되지 않았고, _source로부터 추출된다면 update date를 설정할 것이다.
_source에 추가로 다음과 같은 variable들을 ctx map에 이용할 수 있다. : _index, _type, _id, _version, _routing, _parent, _timestamp, _ttl
07. Delete API :: 2015/05/20 08:56
Delete API는 id를 가지고 특정 index에서 JSON document를 삭제한다. 다음 예제는 twitter index, tweet type, id 값이 1인 JSON document를 삭제하는 것을 보여준다.
$ curl -XDELETE 'http://localhost:9200/twitter/tweet/1'
위 delete operation의 결과는 다음과 같다.
{
"found" : true,
"_index" : "twitter",
"_type" : "tweet",
"_id" : "1",
"_version" : 2
}
Versioning
Index된 각 document는 version이 붙여진다. Document를 삭제할 때, version은 지우려고 하는 document가 실제로 지우려고 하는 것으로 적절한지 삭제하는 동안 변경되지 않는지 확신할 수 있게 한다. Delete를 포함하여 Document에 write operation이 매번 실행될 때마다 버전이 증가한다.
Routing
Routing을 제어하기 위해 indexing을 사용할 때, document를 삭제하기 위해서 routing value가 제공되어야만 한다. 예를 들면 다음과 같다.
$ curl -XDELETE 'http://localhost:9200/twitter/tweet/1?routing=kimchy'
위의 결과는 id 1인 document를 삭제할 것이다. 하지만 사용자 기반으로 route될 것이다. 정확한 route없이 삭제하는 경우 document가 삭제되지 않을 수도 있다.
많은 경우에 routing value는 document를 삭제할 때 주어지지 않는다. 그러한 경우에서는 _routing이 required로 맵핑되었지만 routing이 없으면 전체 shard에 있는 값들을 자동으로 삭제할 것이다.
Parent
Parent parameter가 설정되면, routing parameter가 설정되는 것과 기본적으로 동일하다. Parent document를 삭제하는 것은 그 자식까지 자동으로 삭제하지는 않음에 유의하라. 주어진 id에 해당하는 parent의 모든 자식 document를 삭제하는 한가지 방법은 자동으로 생성되고 index된 field _parent로 child index를 삭제하는 쿼리 (https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html) 를 수행하는 것이다. 형식은 parent_type#parent_id이다.
Automatic index creation
Delete operation은 이전에 생성되지 않았으면 자동으로 index를 생성한다. (수동으로 index를 생성하는 index API를 확인하라). 그리고 이전에 생성되지 않았다면, 자동으로 특정 type에 대해 맵핑되는 type을 동적으로 생성한다. (mapping type을 수동으로 생성하는 put mapping AP?I에 대해서 확인하라.)
Distributed
Delete operation은 hash값으로 해당 shard id를 얻는다. 그리고 그 id group내의 primary shard로 redirect 되고, id group에 속한 shard replica로 (필요하다면) 복제된다.
Replication Type
[WARNING]
1.5.0에서 deprecated됨.
Async replication을 지정하는 것은 deprecate되었고, 버전 2.0.0에서는 삭제될 것이다.
Operation 복제 (replication)는 async 방식으로 replica로 처리될 수 있다. (operation은 primary shard에 수행되고 리턴될 것이다.) replication parameter는 async로 설정될 수 있다. (기본값은 sync이다.)
Write Consistency
Partition 내 (replication group) 에서 Operation이 active shard 수에 근거하여 실행되도록 허용된다면 통제하라. 그 값은 one, quorum, all이 있다. Consistency parameter는 node level 설정에서 기본적으로 action.write_consistency가 quorum으로 설정되어 있다.
예를 들면, 2개의 replica index를 가지는 N개의 shard가 있다면, operation이 성공하기 위해서는 적합한 partition (quorum)내에 최소한 2개의 active shard가 있어야만 할 것이다. 1개의 replica를 가지는 N개의 shard가 있는 시나리오에서는 하나의 shard active가 있어야 한다. (이 경우에는 one 과 quorum이 같다.)
Refresh
Refresh parameter는 적합한 primary를 refresh하고 delete operation이 일어난 이후 replica shard를 통해 검색할 수 있도록 true로 설정될 수 있다. True로 설정하는 것은 시스템에 과부하를 주지 않을 것이라는 주의 깊은 생각과 확신 하에 이루어져야 한다. (indexing하는데 느려질 수도 있다.)
Timeout
Delete operation을 수행하도록 할당된 primary shard는 delete operation이 수행되는 동안에는 이용할 수 없다. 몇가지 이유로 primary shard는 gateway로부터 즉시 복구되거나 재배치를 겪는다. 기본적으로 delete operation은 primary shard가 이용가능해질 때까지 1분을 기다릴 것이다. 그 이후에는 요청이 실패하고 error로 응답한다. Timeout parameter는 얼마나 오래 기다릴지 명시적으로 지정하는데 사용할 수 있다. 다음 예제에서는 timeout값을 5분으로 설정했다.
$ curl -XDELETE 'http://localhost:9200/twitter/tweet/1?timeout=5m'
06. Get API - 02 :: 2015/05/19 20:30
Generated fields
Indexing과 refresh 사이에 refresh가 일어나지 않는다면, GET은 document를 가져오기 위해서 transaction log에 접속할 것이다. 그러나 어떤 fields들은 indexing되는 시점에서만 생성된다. 만약 indexing되는 시점에서만 생성되는 field에 접근하고자 한다면, (기본적으로) exception이 발생할 것이다. 만약 transaction log에 ignore_errors_on_generated_fields=true 설정으로 접근한다면 생성된 필드들 중에서 무시할 필드 (ignore field)를 선택할 수 있다.
Getting the _source directly
Document의 _source field를 조회하기 위해서는 별다른 추가적인 content없이 /{index}/{type}/{id}/_source endpoint를 사용하라. 예를 들면 다음과 같다.
curl -XGET 'http://localhost:9200/twitter/tweet/1/_source'
_source의 일부가 리턴될 때, 제어하기 위하여 마찬가지로 동일한 source filtering parameter를 사용할 수 있다.
curl -XGET 'http://localhost:9200/twitter/tweet/1/_source?_source_include=*.id&_source_exclude=entities'
Document가 존재하는지 효과적으로 테스트하기 위해서 _source endpoint에 대해 HEAD variant를 사용할 수 있다. Curl 예제는 다음과 같다.
curl -XHEAD -i 'http://localhost:9200/twitter/tweet/1/_source'
Routing
Routing을 제어하기 위해서 index를 사용할 경우, document를 조회하기 위해서 routing value를 제공해야 한다. 예를 들면 다음과 같다.
curl -XGET 'http://localhost:9200/twitter/tweet/1?routing=kimchy'
위에서 id 1을 갖는 tweet을 조회할 수 있다. 그러나 user에 기반하여 route될 것이다. 적합한 routing없이 조회하는 것은 document가 조회되지 않는 원인이 될 수도 있다.
Preference
조회 요청을 어느 shard replica가 수행할지는 preference로 제어한다. 기본적으로 operation은 shard replica 사이에 랜덤으로 처리한다.
Preference는 다음 값으로 설정될 수 있다.
_primary : operation은 단지 primary shard에서 수행될 것이다.
_local : operation은 가능하면 local에 할당된 shard에서 수행될 것이다.
Custom (string) value
Custom value는 동일한 shard가 동일한 custom value에 대해서 사용될 것을 보장하는데 사용될 것이다. 이것은 서로 다른 refresh 상황에서 서로 다른 shard에 요청할 때, "jumping value"로 도울 수 있다. Sample value는 web session id나 user name과 같은 어떤 것이 될 수 있다.
Refresh
Refresh parameter는 get operation 전에 적절한 shard를 refresh하고 검색 가능하게 하기 위해서 true로 설정할 수 있다. True로 설정하려면 system상 과부하 (indexing하는데 느려짐) 를 야기하지 않는다는 주의와 확신하에 설정하라.
Distributed
Get operation은 hash하여 해당 shard id를 얻는다. 그리고 그 결과에 따라 shard id에 해당하는 replica들 중 하나로 redirect되고 결과를 리턴받는다. Replica는 primary shard와 shard id group내에 있는 replicas를 의미한다. 이것은 replica가 많을수록 더 좋은 GET scaling을 가짐을 의미한다.
Versioning support
만약 현재 버전이 지정된 것과 동일하다면 Document 조회에 version parameter를 사용할 수 있다. 이것은 항상 document를 가져올 수 있는 version type FORCE를 제외하고 모든 version type에서 동일하다.
Elasticsearch는 document의 예전 버전은 저장하지 않음에 유의하라. 단지 현재 버전만 조회할 수 있다.
05. GET API - 01 :: 2015/05/19 20:30
Get API는 index에서 id로 JSON 형태의 document를 조회한다. 다음 예제는 twitter로 불리는 index, tweet로 불리는 type으로부터 id 값이 1인 JSON document를 얻는 예제이다.
curl -XGET 'http://localhost:9200/twitter/tweet/1'
위의 get operation의 결과는 다음과 같다.
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "1",
"_version" : 1,
"found": true,
"_source" : {
"user" : "kimchy",
"postDate" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
}
위의 결과에는 조회하고자 하는 document가 있을 경우, document에 대한 _index, _type, _id, _version, 실제 document이 내용인 _source가 담겨 있다. (response의 found 필드에 있는 값이 true일 경우 데이터 조회 성공을 의미함)
또한 HEAD를 사용하여 document가 있는지 여부를 체크할 수도 있다. 예제는 다음과 같다.
curl -XHEAD -i 'http://localhost:9200/twitter/tweet/1'
Realtime
기본적으로 get API는 realtime이다. 그리고 index의 refresh rate에 영향을 받지 않는다. (검색한 데이터가 보인다.) realtime GET을 사용하지 못하게 하기 위해서는 realtime parameter를 false로 설정하면 된다. 노드 설정에 있는 action.get.realtime의 글로벌 설정값을 false로 해도 된다.
Document를 얻고자 할 때는 가져오고자 하는 fields를 지정하면 된다. 가능하다면 저장되어 있는 fields를 가져올 것이다. (fields는 저장되어 있는 것과 맵핑되어 있다.) realtime GET을 이용할 경우, 저장된 field라는 개념이 없다. (기본적으로 최소한 다음 flush까지의 기간 동안) 따라서 source 그 자체로부터 추출될 것이다. Realtime GET을 사용할 때, fleldㄴ가 저장된다고 하더라도 source로부터 flelds들이 load된다고 가정하는 것도 좋은 방법이다.
Optional Type
Get API는 _type을 optional로 허용한다. 모든 type에 대해서 Id와 첫번째 match되는 첫번째 document를 가져오기 위해서 _all로 설정하라.
Source filtering
기본적으로 get operation은 fields parameter를 사용하지 않거나 _source field를 사용할 수 없다면, _source field의 content를 리턴한다. _source parameter를 사용하여 _source 검색을 끌 수 있다.
curl -XGET 'http://localhost:9200/twitter/tweet/1?_source=false'
전체 _source에서 한 두개의 field만 필요하다면 필요한 부분을 포함시키는 _source_include와 걸러내는 _source_exclude parameter를 사용할 수 있다. 이것은 network overhead를 줄일 수 있기 때문에 large document로부터 partial retrieval (부분 검색)을 하는 경우 특히나 유용하다. 두 가지 parameter는 콤마로 구분된 field list나 wildcard expression을 가질 수 있다. 예를 들면 다음과 같다.
curl -XGET 'http://localhost:9200/twitter/tweet/1?_source_include=*.id&_source_exclude=entities'
Include의 경우만 처리하고 싶다면 다음과 같이 더 짧게 표기할 수 있다.
curl -XGET 'http://localhost:9200/twitter/tweet/1?_source=*.id,retweeted'
Fields
Get operation은 field parameter를 통해서 리턴받을 저장되어 있는 field를 명시할 수 있다. 예를 들면 다음과 같다.
curl -XGET 'http://localhost:9200/twitter/tweet/1?fields=title,content'
이전 호환성 (backward compatibility)를 위해서 요청된 field가 저장되어 있지 않다면, _source (파싱하여 추출)로부터 가져올 것이다. 이 기능은 source filtering parameter를 통해서 대체할 수 있다.
Document에서 추출된 Field 값은 항상 array로 리턴된다. _routing과 _parent 필드와 같은 Metadata field는 결코 array로 리턴되지 않는다. 또한 leaf field (개별 필드)는 field option을 통해 리턴될 수 있다. 따라서 object field는 리턴될 수 없고, 그러한 요청은 실패할 것이다.
04. Index APIs - 04 :: 2015/05/19 09:05
TTL
Document는 그와 관련된 ttl (Time To Live) 값을 가지고 index될 수 있다. 폐기된 document는 자동으로 삭제된다. Ttl값으로 제공되는 document의 폐기 일자는 document의 index되는 시점이나 값으로 제공되는 어느 특정 시간의 timestamp와 관련되어 있다. 값으로 제공되는 ttl값은 양수값이어야만 하고, milliseconds 단위의 숫자나 다음 예제에서 보여지는 적합한 시간 값이어야 한다.
curl -XPUT 'http://localhost:9200/twitter/tweet/1?ttl=86400000' -d '{
"user": "kimchy",
"message": "Trying out elasticsearch, so far
so good?"
}'
curl -XPUT 'http://localhost:9200/twitter/tweet/1?ttl=1d' -d '{
"user": "kimchy",
"message": "Trying out elasticsearch, so far
so good?"
}'
curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
"_ttl": "1d",
"user": "kimchy",
"message": "Trying out elasticsearch, so far
so good?"
}'
더 많은 정보는 _ttl mappling page (https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-ttl-field.html) 에서 찾아볼 수 있다.
Distributed
Index operation은 위 routing section에서 본 것처럼 직접적으로 primary shard 기반 route하고, shard가 있는 실제 노드에서 수행된다. Primary shard에서 operation이 완료되면, 필요한 경우에, 업데이트는 replica에 분산처리 된다.
Write Consistency
잘못된 network side에 write하는 것을 방지하기 위해서, 기본적으로 index operation은 active shard의 수가 quorum (replicas의 2분의 1 + 1)일 때 성공적으로 수행된다. 이 기본값은 action.write_consistency 설정을 통해서 node-by-node별로 덮어쓸 수 있다. Operation별로 consistency parameter로 보내면 이 값을 변경시킬 수 있다.
유효한 write consistency 값으로는 one, quorum, all이 있다.
Replica의 숫자가 1인 경우 (전체 데이터 복제본이 2개) 에는 기본 동작은 1개의 copy (primary)에서 write가 발생하면, 성공한다.
Asynchronous Replication
[WARNING]
1.5.0에서 삭제되었음. Asynch replication을 지정하는 것은 deprecated (더 이상 사용되지 않고 앞으로 사라질 것으로 마크) 되었고, 2.0.0에서는 삭제될 것이다.
기본적으로 index operation은 replication group에 있는 모든 shard가 document를 index하고 나서 리턴한다. (sync replication임). Asynchronous replication을 사용하기 위해서는 background로 replication process가 일어나기 때문에 replication parameter를 async로 설정해야 한다. Asynchronous replication이 사용될 때, index operation은 primary shard에 성공적으로 operation이 수행되었을 경우에 바로 결과를 리턴할 것이다.
Replication 설정의 기본 값은 sync이다. 그리고 이 기본 값은 action.replication_type 설정을 사용하여 노드별 기본 설정값으로 덮어쓸 수 있다. Replication type의 유효한 값으로는, sync와 async가 있다. Operatio별로 이 동작을 다르게 하기 위해서는 replication request parameter를 이용할 수 있다.
Refresh
Operation이 발생한 이후 즉시 (전체 인덱스가 아니라) shard를 refresh하기 위해서, 그리고 즉시 검색 결과에 operation이 적용된 document가 나타나게 하기 위해서는 refresh parameter를 true로 설정하면 된다. 이 옵션을 true로 설정하는 것은, indexing하는 것과 검색하는 양쪽 상황에서 성능상 문제를 일으키지 않는다는 주의 깊은 생각과 확신 속에서 수행되어야만 한다. Get API를 통해서 document를 조회하는 것은 realtime으로 이루어진다는 것을 유의하라.
Timeout
Index operation을 수행하도록 할당된 primary shard는 index operation이 실행되고 있을 때는 이용할 수 없다. 여기에는 몇 가지 이유가 있는데, primary shard는 gateway로부터 바로 기록되고 재배치가 일어나기 때문이다. 기본적으로 index operation은 primary shard를 사용할 수 있을 때까지 약 1분 정도를 기다린다. 1분 이후에는 실패로 간주하고 오류를 응답한다. Timeout parameter는 얼마나 오래 응답을 기다릴 것인지를 명시적으로 설정하는데 사용된다. 다음 예제에서는 5분으로 설정하고 있다.
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1?timeout=5m' -d '{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}'