2012-08-09 2 views
4

색인 생성에 Lucene.net을 사용합니다. 인덱싱 할 필드 중 하나는 설정되지 않은 값 1에서 6 및 9999가있는 숫자 필드입니다.Luke는 색인의 숫자 필드에 대한 용어 값을 알려줍니다.

Luke을 사용하여 색인을 탐색 할 때 우리는 인식하지 못하는 용어를 봅니다. 지수는 38673 개 문서의 전체를 포함하고 누가는이 필드의 다음 상위 순위 용어를 보여줍니다

Term | Rank | Field | Text | Text (decoded as numeric-int) 
1 | 38673 | Axis | x | 0 
2 | 38673 | Axis | p | 0 
3 | 38673 | Axis | t | 0 
4 | 38673 | Axis | | | 0 
5 | 19421 | Axis | l | 0 
6 | 19421 | Axis | h | 0 
7 | 19421 | Axis | [email protected] | 0 
8 | 19252 | Axis | ` N | 9999 
9 | 19252 | Axis | l | 8192 
10 | 19252 | Axis | h ' | 9984 
11 | 19252 | Axis | [email protected] p | 9984 
12 | 18209 | Axis | ` | 4 
13 | 950 | Axis | ` | 1 
14 | 116 | Axis | ` | 5 
15 | 102 | Axis | ` | 6 
16 | 26 | Axis | ` | 3 
17 | 18 | Axis | ` | 2 

우리는 다른 숫자 필드에 대해 동일한 패턴을 찾을 수 있습니다.

알 수없는 값의 출처는 어디입니까?

답변

4

NumericField는 trie 구조를 사용하여 색인화됩니다. 귀하가 보는 용어는 그것의 일부이지만 검색어를 물으면 결과를 반환하지 않습니다.

정밀도가 Int32.MaxValue 인 단계로 NumericField를 인덱싱하면 값이 사라집니다.

NumericField documentation

는 ... 루씬 내에서, 각 수치는 어느 것이 단순히 낮은 정밀도 표현이다 (각 용어는 논리적으로 더 큰 사전 정의 된 브래킷에 할당 된 트라이 구조로 인덱싱 가치). 연속 된 각 괄호 사이의 단계 크기는 precisionStep이라고하며 비트 단위로 측정됩니다. precisionStep 값이 작을수록 대괄호 수가 많아 지므로 인덱스에서 더 많은 디스크 공간을 사용하지만 범위 검색 성능이 빨라질 수 있습니다. 디스크 공간 소비 대 성능의 균형을 맞추기 위해 기본값 인 4가 선택되었습니다. 값을 변경하려면 전문가 생성자 NumericField (String, int, Field.Store, boolean)를 사용할 수 있습니다. NumericRangeQuery 또는 NumericRangeFilter를 만들 때 일치하는 값을 지정해야합니다. 하위 카디널리티 필드의 경우 더 큰 정밀도 단계가 좋습니다. 카디널리티가 < 인 경우 값 당 하나의 용어를 생성하는 Integer.MAX_VALUE를 사용하는 것이 좋습니다. ... NumericRangeQuery documentation에서 사용할 수있는 정밀 단계에

자세한 내용 :

precisionStep에 대한

좋은 값을 사용하고 데이터 유형에 따라 있습니다

: 모든 데이터 유형에 대한 기본 •

입니다 4, precisionstep이 주어지지 않을 때 사용됩니다. 형식 (길이, 더블) 64 비트 데이터에 대한 대부분의 이상 값 •

6 또는 32 개 비트 데이터 유형에 대해 대부분의 경우에 최적 값 •

제 (INT, 플로우트) 4이다.

• 하위 카디널리티 필드의 경우 큰 정밀 단계가 좋습니다. 카디널리티가 < 인 경우 Integer.MAX_VALUE를 사용하는 것이 좋습니다 (아래 참조).

• long/double의 경우 ≥64 이상이고 int/float의 경우 ≥32이면 인덱스에 값당 하나의 토큰이 생성되고 쿼리는 일반적인 TermRangeQuery만큼 느립니다. 그러나 은 정렬을 위해 전적으로 사용되는 필드를 생성하는 데 사용할 수 있습니다 (이 경우 은 precisionStep으로 간단히 Integer.MAX_VALUE를 사용합니다).필드 캐시를 작성하는 것이 텍스트 전용 숫자보다 훨씬 더 빠르기 때문에 NumericFields를 사용하여 정렬하는 것이 이상적입니다. 이 필드는 값 당 하나의 용어를 가지며 따라서 이라는 고유 한 목록을 작성하기 위해 용어 열거와 함께 작동합니다 (예 : 검색 할 패싯/미리 선택된 값). 위의 precisionSteps 중 하나를 사용하여 범위 쿼리 최적화 필드에서 정렬 할 수도 입니다.

편집 작은 샘플은, 누가 복음 등 값 8192, 9984, 1792,하지만 범위를 사용과 용어를 보여줍니다이에 의해 생성 된 인덱스는 쿼리 나던 생산 결과에 포함 할

:

NumericField number = new NumericField("number", Field.Store.YES, true); 
Field regular = new Field("normal", "", Field.Store.YES, Field.Index.ANALYZED); 

IndexWriter iw = new IndexWriter(FSDirectory.GetDirectory("C:\\temp\\testnum"), new StandardAnalyzer(), true); 

Document doc = new Document(); 
doc.Add(number); 
doc.Add(regular); 

number.SetIntValue(1); 
regular.SetValue("one"); 
iw.AddDocument(doc); 

number.SetIntValue(2); 
regular.SetValue("one"); 
iw.AddDocument(doc); 

number.SetIntValue(13); 
regular.SetValue("one"); 
iw.AddDocument(doc); 

number.SetIntValue(2000); 
regular.SetValue("one"); 
iw.AddDocument(doc); 

number.SetIntValue(9999); 
regular.SetValue("one"); 
iw.AddDocument(doc); 

iw.Commit(); 

IndexSearcher searcher = new IndexSearcher(iw.GetReader()); 

NumericRangeQuery rangeQ = NumericRangeQuery.NewIntRange("number", 1, 2, true, true); 
var docs = searcher.Search(rangeQ); 
Console.WriteLine(docs.Length().ToString()); // prints 2 

rangeQ = NumericRangeQuery.NewIntRange("number", 13, 13, true, true); 
docs = searcher.Search(rangeQ); 
Console.WriteLine(docs.Length().ToString()); // prints 1 

rangeQ = NumericRangeQuery.NewIntRange("number", 9000, 9998, true, true); 
docs = searcher.Search(rangeQ); 
Console.WriteLine(docs.Length().ToString()); // prints 0 

Console.ReadLine(); 
+0

"그러나 어떤 문서에서도 참조되지 않습니다." Lukes의 '용어로 찾아보기'기능을 사용하면이 용어에 대한 많은 문서가 표시됩니다. 실제로 최상위 용어 테이블의 순위와 동일한 양의 문서를 보여줍니다. 예를 들어 9984라는 용어는 19252 개의 문서를 반환합니다. – Vegar

+0

아마도 내 말씨가 잘못되었습니다. 즉,이 값을 쿼리하면 결과가 나오지 않습니다. 나는 질문을 편집하고 관찰 된 행동을 보여주는 샘플을 추가했습니다. –

+0

고마워요! 나는 '용어로 찾아보기'와 '용어에 대한 질의'가 다른 결과를 산출한다는 것을 깨닫지 못했습니다. – Vegar