[Lucene] 5장. 루씬의 고급 검색
Lucene 기초 다지기
출처 : 실전비급 아파치 루씬 7: 엘라스틱서치 검색 엔진을 향한 첫걸음
목차
- 루씬의 이해
- 텍스트 색인
- 텍스트 분석
- 텍스트 검색과 질의 방법
- 루씬의 고급 검색
- 루씬 동작 방식 이해하기
- 다양한 확장 기능
루씬의 고급 검색
1. 검색 결과 정렬
1) 정렬
- 루씬은 사용자 질의에 맞는 도큐먼트를 검색하고, 지정된 순서대로 결과를 정렬한다!
- 정렬 필드에 사용 가능한 타입은
integer
,long
,float
,string
- 사용자 질의와 유사한 정도, 또는 색인된 순서에 따라 정렬할 수 있다.
2) 정렬의 종류
- 유사도 정렬 : 검색 결과를 유사도 점수인
Score
를 기준으로 내림차순 정렬- 점수가 같을 시 도큐먼트 ID 기준으로 오름차순 정렬
- 도큐먼트 ID는 색인 시 부여되는 Key 값으로, 작을수록 먼저 색인됨
- 색인 순서 정렬
- 필드 정렬 : 특정 필드로 정렬할 수 있다. 필드가 색인되어 있어야 하고, 정렬 가능한 타입이어야 함!
- 정렬이 가능한 필드는 저장하지 않고 검색 시에만 활용된다.
- 검색 결과로 내용을 제공하고 싶다면 (저장해야 한다면)
StoreFIeld
+DocValues
둘 다 추가해야 함!
- 다중 필드 정렬 : 여러 필드를 기준으로 정렬하는 다중 필드 정렬도 지원한다.
- [주의] 추가한 순서에 따라 정렬된다.
2. 검색 필터링
1) 검색 필터링 소개
- 수많은 도큐먼트 집합에서 사용자의 검색 의도와 유사한 검색 범위를 줄이는 것은 매우 중요 → 필터링이라 함!
- 검색 필터링은 검색 결과로 도출되는 도큐먼트의 집합을 필터로 축소해 검색 범위를 좁힌다.
- 이전 검색 결과 안에서 재검색 하거나, 보안을 이유로 검색 범위를 제한 할 때 사용된다.
- 쿼리와의 차이점 : 쿼리는 검색어와의 관련성에 따라 순위를 매기지만, 필터는 Score와 관련이 없다!
3. 다중 색인 검색
1) 다중 색인의 필요성
-
대규모 사이트의 경우, 성능과 관리상의 이유로 다중 색인은 검색 엔진 서버 여러 대에 구성한다
-
이럴 경우 다중 색인은 필수적이다!!!
-
하지만 다중 색인 구성에서, 각각의 검색 결과를 직접 취합하는 것은 쉽지 않다.
→ 이럴 경우, 루씬의 다중 색인 검색 클래스인
MultiReader
가 유용하다
-
-
MultiReader
MultiReader
는 도큐먼트를 색인의 고유 이름이 아닌, 정수로 된 도큐먼트 번호로 참조 한다.
2) 다중 색인 사용법
- 색인 구성에서
IndexWriter
객체를 2개 사용했다면, 검색에서도IndexReader
를 2개 써야 한다. - 2개의
IndexReader
를MultiReader
로 구성해, 이걸로IndexSearcher
를 생성한다. - 이렇게 구성한
IndexSearcher
에서 기존 검색과 같이 쿼리를 수행하면,- 다중 색인에서 검색한 결과를 하나로 취합해 받을 수 있다.
4. 텀 벡터
1) 텀 벡터란?
- 검색 결과에서 텀과 함께 도큐먼트의 특정 필드에 출현한 단어와, 단어의 출현 횟수 등 부가적인 정보를 가진 객체다
- 텀의 빈도수 (Term Frequency), 텀의 위치 (Term Position), 텀의 시작 위치 (Term Offset)를 가진다.
- 텀 빈도수 : 특정 도큐먼트에서 텀이 나온 횟수
- 텀의 위치 : 역색인은 텀과 도큐먼트의 위치를 지정함
- 텀의 시작 위치 : 색인 과정에서 텀의 시작과 끝 오프셋을 추적함 → 하이라이팅에 이용!
- 벡터 공간 모델 (Vector Space Model) : 텍스트 도큐먼트를 식별자로 구성된 벡터로 구성하는 대수적 모델
2) 텀 벡터 사용 사례
- 유사도 점수 계산 :
TF-IDF
모델은 이런 벡터 공간을 활용해 질의와 가장 유사한 도큐먼트를 판별한다.- 유사도를 판별하는 기준이 되는 점수를 계산할 때…
- 해당 점수는 도큐먼트가 쿼리와 얼마나 일치하는지를 수치화 한 것인데…
- 이 점수 계산에 벡터 공간 모델이 사용된다
- 질의와 도큐먼트 간의 유사도 점수는
TF-IDF
알고리즘 뿐 아니라 다양한 가중치 알고리즘으로 구할 수 있음
- 유사한 도큐먼트 검색
- MoreLikeThis : 루씬은 특정 도큐먼트와 가장 유사한 도큐먼트를 찾는 MoreLikeThis 기능을 제공함!
- 두 도큐먼트 간의 유사도 계산에 텀벡터를 사용함
- 텀벡터를 저장하면 자연스럽게 색인 용량이 늘어나므로, 반드시 꼭 필요한 경우에만 사용하자!
- MoreLikeThis : 루씬은 특정 도큐먼트와 가장 유사한 도큐먼트를 찾는 MoreLikeThis 기능을 제공함!
- 하이라이팅
- 검색 결과로 도출된 도큐먼트에서 쿼리 텀과 일치하는 텀을 강조하는 하이라이팅 기능 지원!
5. 검색 결과의 점수 계산법
1) Scoring에 대한 이해
- 검색 엔진에서 점수는 연관도 뿐 아니라 순서(Ordering)와도 밀접한 관계가 있다.
- 루씬은 기본적으로 연관도가 높은 순서 대로 정렬하는데, 그 기준이 바로 Score!
- 자연어 분석이 어려운 이유는?
- 같은 의미라도 표현하는 방법이 다르다.
- 같은 단어라도 의미가 모호한 경우가 있다.
- 문맥에 따라서 다른 의미가 될 수 있다.
- 언어에 따라 고유한 특성이 있다.
- 같은 단어라도 상황에 따라서 다르다.
- 루씬의 Scoring
- 루씬은 기본적으로
BM25
라는 알고리즘으로 유사도를 계산함. - 루씬에서의 Score는 도큐먼트간의 거리, 즉 도큐먼트 간의 유사도를 숫자로 표현한 것!
- 루씬은 기본적으로
- 루씬의 다양한 정보 검색 모델
- 불리언 모델 : 루씬 개발 초기에 지원한 벡터 공간 모델!
- 사용자 질의에 따라 참과 거짓 논리로 일치하는 도큐먼트를 찾는다! 간단하고 빠르다
- 프로세스
- 우선 질의와 일치하지 않는 도큐먼트를 적은 부울 모델로 제외
- 검색 모델을 사용해 일치하는 도큐먼트의 순위를 정함 → 스코어링
- 벡터 공간 모델 (Vector Space Model, VSM)
- 확률 모델 (Probabilistic Models)
- 불리언 모델 : 루씬 개발 초기에 지원한 벡터 공간 모델!
2) 유사도
Similarity
: 유사도 점수의 구성 요소를 정의하는 클래스!- 색인과 검색 과정에서 텀에 가중치를 부여하는 방식 결정
- 점수 계산은 필드 기반으로 하고, 그 결과를 결합해 유사도가 높은 결과를 도큐먼트로 반환함
- 색인 과정에서의 유사도 : 유사도를 계산할 때 색인 시 만들어진 텀과 도큐먼트 길이를 보정한 정규화값 (Norm) 사용
- 대부분의 검색에서는 길이가 짧은 필드에 가중치를 준다.
- 정규화 값을 사용하면, 색인 시 도큐먼트 길이를 정규화해 같은 쿼리에 대해 다른 점수 부여 가능!
- 이런 정규화에 사용되는 값이 Norm이고, Norm은 색인 시점에 생성된다.
- 검색 과정에서의 유사도
- 일치 검색 : 어떠한 도큐먼트가 결과에 포함되어야 하는지를 결정
- 스코어링 : 사용자의 질의와 얼마나 유사한지를 점수로 계산
- 가중치를 사용해 계산한 후, 질의와 일치하는 세그먼트를 조회하고 점수를 계싼한 결과를 사용자에게 반환
- 유사도 관련 클래스
Query
클래스 : 사용자 질의, 즉Query
가 없으면 점수를 매길 수 없다.Weight
클래스 : 가중치 관련 클래스- 텀에 대한 통계 정보(
termStatistics
)를 계산하고, 유사도(similarity
)를 계산한다.
- 텀에 대한 통계 정보(
Scorer
클래스 : 모든 점수 계산에 공통 기능을 제공하는 추상 클래스- 점수 계산 외에도, 점수 계산 과정을 설명하는 기능도 제공한다.
IndexSearcher.explain()
메소드를 통해…- 검색 과정에서 특정 도큐먼트의 점수가 어떻게 계산된 건지 살펴볼 수 있다.
3) 가중치와 부스팅
- 부스팅 (Boosting) : 도큐먼트, 필드, 검색 등에 가중치를 두는 것!
- 원리 : 가중치를 주기 원하는 필드의 값을 n배 늘려서 도큐먼트의 빈도를 높이는 것!
- 부스트의 기본값은 1.0이다.
- 만약 1.0보다 큰 값을 설정하면 최종 Score가 높아지고 검색 결과에서 상위에 노출 됨
- 루씬은 검색 시에
Query.setBoost()
를 설정해 부스트 값을 지정한다.- 만약 색인 시에 정해준다면, 부스트 값을 변경할 때 모든 도큐먼트를 다시 색인 해야 했기 때문
- 쿼리에 의해 만드러진 가중치를 이용해
Scorer
객체를 만들고, 부스트 값을 설정함!
- 원리 : 가중치를 주기 원하는 필드의 값을 n배 늘려서 도큐먼트의 빈도를 높이는 것!