본문 바로가기

Lucene

[Lucene 4.X] IndexStatistic from Index

https://builds.apache.org/job/Lucene-Artifacts-4.x/javadoc/core/org/apache/lucene/index/package-summary.html#stats


예전에 루씬4.0이 처음 나왔을무렵에..

인덱스 파일에 대한 통계 정보를 가지고 오는 것을 한번 정리하려고 관련 자료만 스크랩을 해두었었는데요

(http://devyongsik.tistory.com/576)

이번에 관련 스크랩 정보를 사용해서, Lucene 4.4에서 한번 테스트를 해보았습니다.


Junit을 사용한 학습 테스트를 작성하였지만, 시간상 Assert는 사용하지 않고 그냥 값들을 System.out.println으로 출력만 하도록 하였습니다. 이 부분은 나중에 다시 손을 좀 봐야겠습니다. 아무래도 field랑  term을 loop돌면서 처리되는 것들이 많다보니.... 


일단 작성한 테스트 케이스 코드는 아래와 같습니다.



메서드는 4개입니다.

모드 인덱스 파일의 정보를 가져오는 메서드인데 단위가 가장 작은것부터 가져오도록 구성을 해보았습니다.

작은것부터 TermsEnum, Terms, DocsEnum, Segment입니다. 보통 하위 데이터의 sum을 상위 클래스에서 가져올 수 있는 구조로 되어있습니다.


테스트에 사용된 문서는 아래와 같습니다.


doc1

 - contents : sir lion

 - contents2 : the hadoop


doc2

 - contents : tiger

 - contents2 : hadoop drive


doc3

 - contents : the wolf lion

 - contents2 : tool


메서드별로 출력결과와 함께 간단한 설명을 붙여보도록 하겠습니다.


1. commonStatisticsFromTermsEnum

출력결과

fieldName : contents

doc Freq of [lion] : 2

total term Freq of [lion] : 2

------------------------------------

doc Freq of [sir] : 1

total term Freq of [sir] : 1

------------------------------------

doc Freq of [the] : 1

total term Freq of [the] : 1

------------------------------------

doc Freq of [tiger] : 1

total term Freq of [tiger] : 1

------------------------------------

doc Freq of [wolf] : 1

total term Freq of [wolf] : 1

------------------------------------


fieldName : contents2

doc Freq of [drive] : 1

total term Freq of [drive] : 1

------------------------------------

doc Freq of [hadoop] : 2

total term Freq of [hadoop] : 2

------------------------------------

doc Freq of [the] : 1

total term Freq of [the] : 1

------------------------------------

doc Freq of [tool] : 1

total term Freq of [tool] : 1

------------------------------------


##########################################


2개의 메서드가 제공되는데 하나는 TermsEnum.docFreq이고 하나는 TermsEnum.totalTermFreq입니다.

docFreq는 해당 Term이 그 필드에 존재하는 document의 개수입니다. [hadoop]을 보시면 docFreq가 2인것이 확인 가능하지만, [the]에 대해서는 각 필드별로 1씩 나눠져 나오는것을 보실 수 있습니다. 필드가 다르기 때문에 나타나는 결과입니다.

totalTermFreq는 전체 document의 필드에서 해당 Term이 나오는 횟수입니다. 마찬가지로 필드별로 계산됩니다.


2. commonStatisticsFromTerms

출력결과

size : 5

doc count : contents : 3

sum of doc freq : contents : 6

sum of total term freq : contents : 6

------------------------------------

size : 4

doc count : contents2 : 3

sum of doc freq : contents2 : 5

sum of total term freq : contents2 : 5

------------------------------------

4개의 메서드를 사용했습니다. Terms.size, Terms.getDocCount, Terms.getSumDocFreq, Terms.getSumTotalTermFreq 입니다.


Terms.size는 중복되는 Term을 제외한 그 필드의 Term 개수입니다. contents에서는 [the]가 contents2 [hadoop] term이 중복이며 그로인해 각각 5와 4의 값을 갖습니다.


Terms.getDocCount는 해당 필드에 term이 하나라도 있는 document의 개수입니다. 전체 document가 3개이고 각 document가 모두 필드에 term을 가지고 있으므로 동일하게 3의 값을 갖습니다.


Terms.getSumDocFreq는 해당 필드에서 TermsEnum.docFreq의 합입니다. 모든 term의 freq의 합을 뜻하게 되지요.. 여기서는 contents는 6, contents2는 5를 갖습니다. 이는, 첫번째 테스트에서 나온 TermsEnum.docFreq의 합과 같습니다.


Terms.getSumTotalTermFreq는 해당 필드에서 TermsEnum.totalTermFreq의 합입니다. 즉, 전체 document에서 이 필드에 전체 term의 freq 합입니다. TermsEnum이 term별 freq였다면 이건 이 term별 freq를 합한 값이 되겠죠..


3. commonStatisticsFromDocEnums

출력결과

freq from docsEnum : 1

freq from docsEnum : 1

##########################################

메서드는 하나입니다. DocsEnum.freq...

다만, DocsEnum을 받아올때의 메서드를 보면 

DocsEnum docsEnumForContents = MultiFields.getTermDocsEnum(directoryReader, MultiFields.getLiveDocs(directoryReader), "contents2", new BytesRef("hadoop"));

이렇게 되어있는데요... 필드와 term을 파라메터로 넘겨주고있습니다. 즉, 이 테스트에서는 전체 document에서 contents2 필드에 hadoop term을 가진 document들의 DocsEnum을 넘겨받게 되고... 2개의 document가 존재하므로 위와 같은 결과가 나오게 됩니다. 


만약 doc2의 contents2가 hadoop drive hadoop이라면 결과가 조금 다르겠죠..

아래와 같이 나올것입니다.

freq from docsEnum : 1

freq from docsEnum : 2

##########################################



4. commonStatisticsFromSegment

실행결과

max doc : 3

num docs : 3

deleted docs : 0

sum of doc freq : 6

sum of total term freq : 6

doc freq having this term in field : 2

##########################################

비교적 명료하게 때문에 자세한 설명은 생략하고... 대신 freq를 가져올 때 필드명을 지정한다는 것과 맨 마지막 docFreq 메서드에서는 Term 객체를 같이 넘겨준다는 것만 잘 보시면 될것 같습니다.


그외에도 몇가지가 더 있는것 같은데... 필요할때마다 찾아봐야할것 같습니다.


특히, FieldInvertState 클래스로 역인덱스 파일의 통계값을 많이 가져올 수 있는것 같은데 이걸 어떻게 얻어내는지 잘 모르겠네요... 더 공부가 필요할것 같습니다.


자세한 내용은 http://lucene.apache.org/core/4_4_0/core/org/apache/lucene/index/package-summary.html#termstats 에서도 확인 가능합니다.


테스트코드는 아래의 경로에 있습니다.

https://github.com/need4spd/aboutLucene/blob/master/lucene-4.x/src/test/java/com/tistory/devyongsik/indexing/IndexStatisticsTest.java