[강좌]Lucene Index File Format-4 (마지막)

마지막 강좌이다. 이곳에서는 텀벡터(Term Vectors)를 저장하는 방식과 삭제되는 문서들을 어떻게 저장을 하는지에 대해서 알아보도록 한다.

Term Vectors

1) 텀 벡터 인덱스 파일 또는 .tvx 파일

이 파일은 Document(.tvd)안에있는 문서 정보에 대한 포인터를 제공한다.

<구조 요약>
DocumentIndex (.tvx) –> TVXVersion<DocumentPosition>^NumDocs

<각 인자별 자료형 정의>
TVXVersion –> Int

DocumentPosition –> UInt64

문서 갯수만큼 .tvd파일로의 파일 포인터 정보를 저장하고 있다. (TVXVersion는 현 파일의 버전 정보저장)

2) 텀 벡터 문서 파일 또는 .tvd 파일

이 파일은 .tvx 파일에서 포인팅한 문서정보를 포함하고 있다. 문서정보라 함은 필드갯수만큼의 각 필드당 필드에 포함된 텀에 대한 정보를 가지는 파일(.tvf)로의 파일 포인터를 저장하고있다.

<구조 요약>
Document (.tvd) –> TVDVersion<NumFields, FieldNums, FieldPositions>^NumDocs

<각 인자별 자료형 정의>
TVDVersion –> Int

NumFields –> VInt

FieldNums –> <FieldNumDelta>^NumFields

FieldNumDelta –> VInt

FieldPositions –> <FieldPosition>^NumFields

FieldPosition –> VLong

FieldPosition정보는 다음에 나올 .tvf로의 파일 포인터값을 가지고 있다.

3) 텀 벡터 필드 파일 또는 .tvf 파일

이 파일은 실제 텀 벡터가 포함된 파일이다. 그러니까 텀과 그의 빈도가 연속적으로 저장된 구조다.

<구조 요약>
Field (.tvf) –> TVFVersion<NumTerms, NumDistinct, TermFreqs>^NumFields

<각 인자별 자료형 정의>
TVFVersion –> Int

NumTerms –> VInt

NumDistinct –> VInt — 나중에 쓰일 예정임

TermFreqs –> <TermText, TermFreq>^NumTerms

TermText –> <PrefixLength, Suffix>

PrefixLength –> VInt

Suffix –> String

TermFreq –> VInt

텀 텍스트와 문서내 빈도수를 저장을 한다. 그리고 정렬은 알파벳 순으로 저장이 되어서 Text 자체를 <PrefixLength, Suffix> 쌍으로 압축해서 저장을 할 수 있다. 이 압축 방법은 앞의 강좌에서 설며을 했으니 넘어가도록 한다.

생각해보면 Term Dictionary가 있는데 굳이 왜 이런 Term Vectors 파일들을 유지를 할까 하는 생각이 들었다. 개인적인 생각을 적어본다. (이 부분에 대해서 다른 의견이 있으며 뎃글 바란다. ^^;)

텀 사전은 말 그대로 역파일 구조를 위한 자료구조이다. term에서 시작해 문서 번호 그리고 t.f 및 다른 정보에 접근을 하는 것이다. 하지만 순위를 구할때 쓰이는 “tf(t in d)”의 경우에는 역으로 문서에서 해당 텀을 접근해야만이 쉽게 접근이 가능할 것이다. 만일 Term Vectors 파일이 없다면 원하는 term에 접근하기 위해 수십 수백번의 디스크 엑세스를 해야할 것이다. 그리고 만일 찾는 문서번호의 텀이 그 해당 세그먼트에 없는 경우에는 다른 세그먼트에서 원하는 문서번호와 텀정보를 찾기 위해서 또한 수십 수백의 디스크 엑세스를 해야 할 것이다. 만일 이런작업이 세그먼트 최적화 작업하기 전의 이야기라면 더 많은 시간이 걸릴것임에 분명할 것이다. 그래서 위와 같은 Term Vectors 같은 파일들을 따로 저장을 해서 랭킹계산시 빠른 속도로 수행을 하기위함이라는 예상을 해본다.

개인적인 생각은 위와 같다. 이 부분에 대한 정확한 답은 메일링 리스트를 검색해보거나 다른 자료를 찾아봐야 겠지만 두 자료구조의 구조를 비교해봄으로서 목적을 생각해 봤을때 이러할 것이라는 생각을 해본다.

Deleted Documents

.del 파일은 옵션이다. 그리고 오직 세그먼트가 삭제할것을 포함하고 있을때 존재한다.
그러니까 삭제할 문서를 표시해놓는 비트정보 파일인 셈이다.

<구조 요약>
Deletions (.del) –> ByteCount,BitCount,Bits

<각 인자별 자료형 정의>
ByteSize,BitCount –> Uint32

Bits –> <Byte>^ByteCount

ByteCount는 Bits안에 있는 바이트수를 의미한다. 일반적으로 ‘(SegSize/8) + 1’ 이 된다.
1비트에 삭제될 문서인지 아닌지 명시할 수 있으므로 잘 생각해보면 이해가 될 것이다.

BitCount는 Bits에 있는 비트의 갯수를 의미한다.

Bits는 각 인덱스된 문서에 대해서 1비트를 할당한다. 그래서 해당 비트가 1로 표시가 되어 있으면 삭제된 문서가 되는 것이다. Bit 정렬순서는 낮은 비트부터 높은 비트로 정렬이 된다.(이렇게 해야 문서 번호대로 비트들이 ordering이 된다.) 만일 Bits가 2바이트이고 0x00 과 0x02로 되어 있으면, 문서번호 9는 삭제된 문서로 표시가 되는 것이다. (이진수로 표현하자면 ‘0000 0000 0100 0000’)

제한(Limitation)
이 루신 파일 포멧은 40억개의 텀과 문서로 한정한다. 이것은 일반적으로 큰 문제가 되지 않는 처리량이고 나중에 이런 부분은 UInt64나 더 제한이 없는 VInt형으로 대체될 것이다.

End and 소감ㅋ~——————————————————-

드뎌 파일 포멧 분석을 완료 했다. 무엇보다 왜 이런 구조로 했는지에 대해서 일방적으로 문서에서는 제시를 하고 있어서 소스코드를 병행해서 보고, 또한 인터넷을 뒤져가며 많은 고민을 했었다. 결국엔 파일 포멧 어느부분 배울게 없는곳이 없었다. 개인적으로 색인DB에 대해서 아주 양질의 코드와 문서로 공부를 했다는 생각이 든다. 자바로 만들어져 있지만 Verity사의 상용검색엔진을 경쟁상대로 할 정도로 완성도 높은 구조와 성능을 자랑한다는게 과장은 아님을 알 수 있었다.

전에 바쁘게 “루씬 인덱스 파일 포멧“이라는 문서를 번역할때 애매한 부분을 완벽하게 이해를 했다는점이 가장 큰 수확이였고, 아마도 지금까지 해온 강좌에 다 묻어나 있을거라는 생각이든다.

앞으로는 이것을 기반으로 틈틈히 루씬 프로젝트에 손을 대볼까 하는 생각도 하고 있다. 루씬 오픈소스 프로젝트에 참여하는 사람은 많지만 핵심을 건드릴 수 있는 사람이 절대적으로 부족하다는 더그커팅의 말도 있기도 하고 좀 알고나니 욕심이 나는 부분도 있는게 사실이기 때문이다.

마지막으로 이런 좋은 공부거리를 제공해준 Lucene을 개발한 개발자들에게 감사를 보넨다.

CC BY-NC 4.0 [강좌]Lucene Index File Format-4 (마지막) by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.