ES Document 다루기

JB·2022년 1월 25일
0

ElasticSearch

목록 보기
3/3

이번 포스트에서는 Document를 다루는 API에 대해 알아볼 예정이다.

Index 생성

PUT /books 
{ // 아래 이 부분은 옵션으로 생략 가능
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 2
  }
}
{
  "acknowledged" : true, // 생성 결과
  "shards_acknowledged" : true,
  "index" : "books"
}

Index 삭제

DELETE /books

Document Index

Index에 Document를 삽입하는 것을 인덱싱이라고 한다.

POST /books/_doc
{ 
  "name": "The Hitchhiker's Guide to the Galaxy",
  "author": "Douglas Adams",
  "date" : 1987
}

POST body로 document 생성

{
  "_index" : "books",
  "_type" : "_doc",
  "_id" : "tw5CkX4B9NTpFVLoxw9B",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 3,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 2
}

위의 결과에서 눈 여겨 볼 점은 _shards 정보와 _id 정보이다.

샤드와 관련된 내용

앞서 인덱스를 생성할 때 2개의 샤드, 2개의 레플리카를 설정했기 때문에
1개의 프라이머리 + 2개의 레플리카 샤드로 구성되어 총 3개가 생성되어야 정상이다.
하지만 필자의 경우 노드 2개를 실행시킨 상황이다.
동일한 내용의 레플리카가 같은 노드에 생성될 이유가 없기 때문에 2개만 생성된 상황이다. (프라이머리 1개 + 레플리카 1개)
이렇게 되더라도 우선 기능적인 상황에 문제는 없다
다만, status가 green은 아니기 때문에, 데이터 손실에는 주의할 필요가 있는 상태이다.
status와 관련된 내용은 alden 님의 글을 참고하자.

ID와 관련된 내용

위 결과를 보면 _id가 해시값으로 되어있는 것을 볼 수 있다.
인덱스 내에서 ID는 유일해야하기 때문에, ES가 자체적으로 해시값을 계산해 중복되지 않도록 처리를 한 것이다.
그렇다면, 내가 원하는 ID를 부여할 순 없을까?
아래와 같이 ID를 지정해서 인덱싱이 가능하다.

POST /books/_doc/409
{
  "name": "Operating system concepts",
  "author": "Abraham Silberschatz",
  "date" : 2013
}
{
  "_index" : "books",
  "_type" : "_doc",
  "_id" : "409", // 지정한 ID로 인덱싱되었다
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 3,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 2
}

위 예시에서는 ID를 숫자로 지정했지만, 문자열이여도 상관없다.
또한, action.auto_create_index 옵션이 활성화 되어있다면, document 인덱싱 시에 일치하는 인덱스가 없다면 해당하는 인덱스를 생성 후 인덱싱을 진행한다.

Document 검색

document ID를 알고 있는 경우, 아래와 같이 HTTP Verb만 변경하면 검색이 가능하다.

GET /books/_doc/409
{
  "_index" : "books",
  "_type" : "_doc",
  "_id" : "409",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 2,
  "found" : true,
  "_source" : {
    "name" : "Operating system concepts",
    "author" : "Abraham Silberschatz",
    "date" : 2013
  }
}

하지만, 핵심은 document ID를 모르고 있을 경우이다.
모를 경우 _search API를 이용하면 필드 별로 BM25 스코어를 계산하여 검색해준다.
BM25는 문서와 질의어의 relevance를 계산해주는 방법이다.
relevance가 높을수록 질의어와 문서간의 연관성이 높다고 판단한다.
자세한 내용은 꽤나 복잡하기 때문에, 링크로 설명은 대체한다.

GET /books/_search
{
  "query": {
    "match": {
      "name": "operating"
    }
  }
}
{
  "took" : 82,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.8025915,
    "hits" : [
      {
        "_index" : "books",
        "_type" : "_doc",
        "_id" : "409",
        "_score" : 0.8025915,
        "_source" : {
          "name" : "Operating system concepts",
          "author" : "Abraham Silberschatz",
          "date" : 2013
        }
      }
    ]
  }
}

위 결과 중 _score가 BM25 score이다.
따라서 여러 문서가 검색될 경우, 가장 score가 높은 문서가 높은 우선순위를 가지게 된다.

profile
평범한 월급쟁이 개발자

0개의 댓글