[英]How to search an int field in Lucene 4?
我正在嘗試實現文檔索引(對應於DB行的rougly),其中一個字段是整數。 我將它們添加到索引中:
Document doc = new Document();
doc.add(new StringField("ticket_number", rs.getString("ticket_number"),
Field.Store.YES));
doc.add(new IntField("ticket_id", rs.getInt("ticket_id"),
Field.Store.YES));
doc.add(new StringField("id_s", rs.getString("ticket_id"),
Field.Store.YES));
w.addDocument(doc);
好像我根本無法查詢ticket_id
字段,而id_s
工作得很好。
其中一個文件是(為了便於閱讀,我添加了空格):
Document<
stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<ticket_number:230114W>
stored<ticket_id:152>
stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<id_s:152>>
所以我的int字段存儲,但沒有索引。 此查詢按預期工作: id_s:152
,而此查詢從不返回任何內容: ticket_id:152
。
我究竟做錯了什么? 如何將這樣的字段添加到索引並使其可搜索?
以下對我有用:
RAMDirectory idx = new RAMDirectory();
IndexWriter writer = new IndexWriter(
idx,
new IndexWriterConfig(Version.LUCENE_40, new ClassicAnalyzer(Version.LUCENE_40))
);
Document document = new Document();
document.add(new StringField("ticket_number", "t123", Field.Store.YES));
document.add(new IntField("ticket_id", 234, Field.Store.YES));
document.add(new StringField("id_s", "234", Field.Store.YES));
writer.addDocument(document);
writer.commit();
IndexReader reader = DirectoryReader.open(idx);
IndexSearcher searcher = new IndexSearcher(reader);
Query q1 = new TermQuery(new Term("id_s", "234"));
TopDocs td1 = searcher.search(q1, 1);
System.out.println(td1.totalHits); // prints "1"
Query q2 = NumericRangeQuery.newIntRange("ticket_id", 1, 234, 234, true, true);
TopDocs td2 = searcher.search(q2, 1);
System.out.println(td2.totalHits); // prints "1"
正如femtoRgon所指出的,對於數值(long,date,float等),您需要使用NumericRangeQuery
並指定精度。 否則Lucene不知道你想如何定義相似性。
可以使用NumericRangeQuery查詢數字字段。 要獲得完全匹配,只需將max和min設置為相等的值即可。
指示字段未編入索引的輸出可能是由於與文本值相比,數值的索引方式不同。 考慮到該字段被轉換為Lucene的數字表示,字面值152
確實不會被索引
但是,乍一看,您對id_s的處理可能是更好的選擇。 ID通常不作為數值處理,而是作為恰好用數字表示的簡單標識符。 如果您不需要對字段進行數字排序或范圍查詢,那么索引作為StringField
肯定更有意義。
另一個答案來自這個帖子(第三個答案): Lucene 4.0 IndexWriter updateDocument for Numeric Term
基本上,您使用int值創建一個Term,如下所示:
String field = "myfield";
int value = 4711;
BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT);
NumericUtils.intToPrefixCoded(value, 0, bytes);
Term term = new Term(field, bytes);
然后,您可以使用此術語進行搜索,或刪除/更新索引。 在第一次測試中,這對我來說很好。 我無法分辨這是否是“正確”的做事方式。 我之前使用NumericRangeFilter來過濾IntFields,但現在我傾向於使用這種方法並使用常規的TermsFilter或TermQueries。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.