본문 바로가기

목록이 없습니다.

[Elasticsearch] 업데이트 시 해당 document 존재여부에 따라 update(script) or create

Server/Elastic Search
    반응형

    Elasticsearch(이하 ES)는 보통 쌓인 데이터들을 ES구조로 컨버팅해서 대용량의 데이터를 인덱싱하여 빠르게 찾아볼 수 있도록 하는데 많이 사용되는데 이번 프로젝트 같은 경우에는 ES를 DB 처럼 사용해보았습니다. ES에 바로 데이터를 insert, update, delete를 하는 로직을 짜보았는데요, 그러다가 update 과정에서 벽에 부딪혔는데 해결 방법을 찾아서 정리해보려고 합니다.

     

     update를 하는데 처음에 로직을 기존 RDB처럼 해당 문서의 ID로 조회하여 문서의 존재 여부를 판단하고 없으면 insert(ES에서는 create문)를 존재하는 경우 update문을 날리도록 하였습니다. 그런데 서로 다른 여러 서버에서 쿼리문을 날리다보니 조회하는 시점에는 없던 문서였는데 다른 서버에서는 이미 생성중인 경우가 생기면서 일부 쿼리문들이 씹히는(?) 현상이 일어나기 시작했습니다.

     

     그렇게 구글링을 시작하였고 조회해서 문서 유무를 판단하는 것이 아니라 하나의 쿼리문을 던져서 ES에서 알아서 판단해주는 방법을 찾았습니다. 조회하여 판단하는 로직은 불안했던 요소가 ES는 어떤 데이터가 입력이 되면 바로 조회할 수 있는 것이 아니라 인덱싱하는 과정을 거치기 때문에 인덱싱하는 동안에는 조회가 되지 않습니다. 따라서 이미 들어가있음에도, 이미 문서가 생성되어있음에도 없다고 조회되는 경우가 꾀 자주 일어나기도 했고 불안요소를 제거하기 위해서 로직을 변경했습니다.

     


    Upsert & Script

    POST test/_update/1
    {
        "script" : {
            "source": "ctx._source.counter += params.count",
            "lang": "painless",
            "params" : {
                "count" : 4
            }
        },
        "upsert" : {
            "counter" : 1
        }
    }

    결론적으로 위와 같이 쿼리문을 날리면 test 인덱스의 _id가 1인 문서가 이미 존재하는 경우에는 script 문이 실행이 되고 문서가 없는 경우에는 아래에 upsert문이 실행이 됩니다. 위의 쿼리문을 해석해보면 이미 존재하는 경우에는 문서의 필드인 counter에 4를 더하고 없는 경우에는 counter를 1로 초기화하는 쿼리문입니다.

     

    위의 쿼리문 한방으로 기존에 복잡하고 불안했던 로직이 해결되었습니다.

     

    참고

    ES사이트

    반응형