단건 문서에 대한 API
-색인 API
PUT [인덱스명]/_doc/[_id]
POST [인덱스명]/_doc #id 값을 명시하지 않을 땐 POST를 써야함
PUT [인덱스명]/_create/[_id]
POST [인덱스명]/_create/[_id]
1. 가장 기본적인 방법임. 해당 _id가 이미 존재한다면, 덮어씌운다.
2. id 값을 명시하지 않으려면 POST를 사용한다. 엘라스틱 서치가 고유한 _id를 자동 생성한다.
3. _id가 이미 존재한다면, 오류를 띄운다.
값을 색인할 땐, 되도록 라우팅 값을 넣어주는 것이 좋다.
넣지 않는다면 _id 값을 기반으로 샤드가 지정된다.
PUT [인덱스명]/_doc/1?routing=myid
refresh
색인 시, 위 값을 지정하면 색인 이후 바로 refresh 되어 즉시 검색이 가능해진다.
그러나 이는 비용이 큰 작업이다. 호출량이 많으면 성능이 저하될 수 있으며 너무 많은 작은 세그먼트를 생성한다.
작은 세그먼트가 많으면 색인 이후 검색 기능도 떨어지며 추후 세그먼트 병합 과정의 부담이 커질 수 있다.
- true: 즉시 refresh
- wait_for: 색인 이후, 문서가 refresh 될 때까지 기다린 후 응답을 반환함. refresh를 바로 유발하진 않지만, 대기가 많아지면 강제로 refresh 됨
- false: 기본 값. refresh와 관련된 동작을 하지 않는다.
wait_for은 index.refresh_interval 값의 크기만큼 응답 시간이 지연될 수 있다. 대신, 대기 중인 문서 갯수가 1000이 넘으면 강제 refresh 된다.
이 값은 index.max_refresh_listeners 설정에서 변경할 수 있다.
단, 대량의 색인이 필요한 경우엔 bulk API를 사용해야 한다.
조회 API
조회API는 검색API와는 다르다. 일단, 색인이 refresh 되지 않은 상태에서도 값을 확인할 수 있다.
조회 API는 애초에 고유한 식별자를 지정하여 단건 문서를 조회하는 것이기 때문에 역색인을 타지 않으며 translog에서 데이터를 읽어올 수 있기 때문이다.
GET [인덱스명]/_doc/[_id]
GET [인덱스명]/_source/[_id]
# 원하는 필터만 필터링 —> _source_includes, _source_excludes 사용
GET [인덱스명]/_doc/[_id]?_source_includes= 값
ex) GET [인덱스명]/_doc/[_id]?_source_includes=p*,view
# p로 시작하는 필드와 view 라는 필드만 결과로 반환된다.
기본적인 조회엔 _doc을 이용하면 된다. 인덱스, _id 등 기본 메타 데이터를 함께 조화할 수 있다.
메타데이터 없이 문서 본문만 원한다면 _source 로 지정하여 호출하면 된다.
업데이트 API
detect_noop
실제로 필드 내용이 변경되었는지 확인함. 변경된게 없으면 작업을 수행하지 않음.
이 경우, 업데이트 api 의 결과 값이 “result”: “noop” (=> no operation) 이 됨.
이를 검사함으로써 불필요한 디스크 I/O 를 감소시킨다.
그러나, 똑같은 내용으로 업데이트가 일어날 일이 전혀 없다고 가정할 때, 이 기능을 비활성화 하면 검사 과정이 생략되기에
성능에 약간 향상시킨다.
doc_as_upsert
update 대상이 없으면 insert 한다는 뜻이다. 이 기능을 원하면 옵션으로 true 를 주고 실행하면 된다.
doc을 이용하지않고 스크립트를 이용하여 수행도 가능하다.
위 옵션에서도 물론 라우팅과 refresh 옵션을 이용하여 쿼리를 수행할 수 있다.
삭제 API
DELETE [인덱스명]/_doc/[_id]
이때.. DELETE [인덱스명] 으로 쿼리를 날리면 인덱스 전체가 삭제되기 때문에 매우매우 주의해서 쿼리를 날려야한다.
복수 문서 API
엘라스틱 서치의 API는 기본적으로 HTTP를 이용한다. 데이터 한건 단위로 HTTP를 날리는 것과 복수의 문서를 하나의 HTTP에 담아 보내는 것은 성능 차이가 크기에, 여러 문서를 다룰 때는 bulk API와 multi get API를 쓰는 것이 좋다.
bulkAPI는 json이 아닌 ndjson을 이용한다.
(ndjson : json을 줄단위로 구분하는 형태)
Context-Type도 application/json이 아닌 application/x-ndjson이다. 마지막 줄바꿈 문자도 \n 으로 끝나야한다.
POST _bulk{
{“index”: {“_index”: “bulk_test”, “_id”:”1”}}
{“field”:”value”}
{“delete”: {“_index”: “bulk_test”, “_id”:”2”}}
{“create”: {“_index”: “bulk_test”, “_id”:”3”}}
{“field”:”value”}
{“update”: {“_id”: “1”, “_index”:”bulk_test”}}
{“doc”: {”field”: “value}}
{“index”: {“_index”: “bulk_test”, “_id”:”4”, “routing”: “a”}}
{“field”:”value”}
}
### 총 5개의 명령임 ####
{“index”: {“_index”: “bulk_test”, “_id”:”1”}}
{“field”:”value”}
{“delete”: {“_index”: “bulk_test”, “_id”:”2”}}
{“create”: {“_index”: “bulk_test”, “_id”:”3”}}
{“field”:”value”}
{“update”: {“_id”: “1”, “_index”:”bulk_test”}}
{“doc”: {”field”: “value}}
{“index”: {“_index”: “bulk_test”, “_id”:”4”, “routing”: “a”}}
{“field”:”value”}
들어간 _bulk는 기본 인덱스다. 필드 내부에 인덱스를 따로 명시하지 않으면 해당 기본 인덱스가 들어간다.
결과도 벌크형식으로 온다. 각 명령에 대한 result가 200 또는 404 등으로 오기 때문에. 클라이언트 측에서 해당 필드를 파싱해서 봐야한다.
작업 순서는 명시한 리스트들 대로 지켜지는 것은 아니다.
조정노드가 해당 요청을 수신하면, 요청의 내용을 보고 적절한 샤드로 요청을 넘긴다. 여러 개 샤드에 넘어간 요청은 독자적으로 수행된다.
만약 동일한 인덱스, _id, 라우팅 조합을 가진 요청이라면 반드시 동일한 샤드로 넘어가기 때문에 그 샤드에서 일어나는 것은 기술한 순서대로 동작한다.
몇개 이상일 때, 묶는다. 이런 명확한 기준은 없다. 그러나 단건 API를 여러번 호출하는 것보다는 월등히 빠르니, bulk API를 쓰자.
multi get API는 _id를 여러개 지정하여 여러 개의 문서를 한번에 조회하는 방법이다.
단건 조회 API를 여러번 반복하는 것 보다 이 방법이 더 성능에 좋다
GET _mget
GET [인덱스명]/_mget
GET _mget
{
“docs”: [
{“_index”: “bulk_test”, “_id”: 1},
{“_index”: “bulk_test”, “_id”: 4, “routing”: “a”}, {“_index”: “bulk_test”, “_id”: 1m “_source”: {“include”: [“p*”], “exclude”: [“point”]}}
]
}