Data Engineering/Distributed System

[OpenSearch] - 3. Inverted Index ( 역인덱스 )

cstory-bo 2024. 1. 6. 16:24

Opensearch의 인덱싱은
검색 효율을 높이기 위해 데이터를 구조화하는 방법이다.

이번에는 이 방법에 대해 자세히 알아보려고 한다.

Inverted Index

OpenSearch의 빠른 검색 성능은 역인덱스로부터 나온다.
역인덱스의 목적은 효율적이고 빠른 전문 검색이 가능하게 하는 것이다.

전문 검색은 특정 단어가 포함된 문서를 찾아내는 검색 방식을 말한다.

기존 RDBMS에서는 전문 검색을 하면 레코드 하나하나씩 테이블 전체를 풀스캔하기에 속도가 느리다.
OpenSearch는 토큰화된 역인덱스 데이터에 대해 쿼리를 진행하기에 빠르다. 

출처:  https://stackoverflow.com/questions/47003336/elasticsearch-index-sharding-explanation

역인덱스는 필드 수준에서 작동하기에 각 Text 타입 필드마다 하나씩 가지고 있다.

위 그림은 도큐먼트를 추가할 때 character filter -> tokenizer -> token filter를 거쳐 역인덱스로 구조화되는 과정을 보여준다.

token filter까지 거친 단어들을 Term 이라고 하며
역 인덱슨느 이러한 Term에 대해 등장하는 도큐먼트의 정보들을 저장한다.
예) coffee : 1, 4, => coffee라는 term 이 등장한 도큐먼트들은 1, 4이다.

한마디로 역인데스는 Term 과 Term이 포함된 Document 간의 매핑이라고 볼 수 있다.

Query

이제 인덱싱 방법을 알아보았으니, 쿼리가 동작하는 방법을 알아보려고 한다.

데이터를 검색할 떄 2가지 방법이 있다.

1. Full-text query

2. Term-level query

Full-text Query

전문 검색을 위해 사용되며
검색어와 도큐먼트가 일치하는 정도에 따라 score를 계산하고 높은 순으로 내림차순 정렬하여 보여준다.

검색어는 인덱싱 당시 사용된 분석기와 동일한 분석기가 사용된다.
이 쿼리는 Text 타입만 사용가능하다.

아래 예시의 review필드의 타입은 text이다.

Term-level Query

용어 수준의 쿼리는 검색어와 정확히 일치하는 용어를 찾는다. 대소문자 구분도 포함이다.
keyword 타입 검색에도 많이 사용되지만 아니더라도 사용 가능하다.

여기서 Category 필드는 keyword 타입이다.

만약 bread 나 Bread. 으로 검색하면 결과값을 얻을 수 없을 것이다.

위에 있는 review 텍스트를 그대로 복사해서 Term-level로 검색해보았다.

하지만 아무런 결과를 얻지 못한 것을 알 수 있다.

분명 해당 텍스트가 있는데도 결과를 못 얻은 이유는 text analyzer과 여러 필터들 때문이다.
text타입 필드에 한해서 인덱싱떄와 같은 텍스트 분석 프로세스를 거치기에 검색 쿼리에 넣은 문장이 소문자로 변환되고 마침표도 삭제되었을 것이다.
하지만 용어수준의 쿼리이기에 기존 텍스트와 대문자, 마침표가 달라 일치하지 않는다는 결과가 뜨는 것이다.

소문자 bread로 용어수준으로 검색해보면 어떨까?

결과가 나온다.
이를 통해 "Bread is a ~" 문장은 실제로는 bread, is, staple,...등 텍스트 분석 프로세스를 거친 term으로 저장되었다는 것을 알 수 있다.