簡體   English   中英

如何在Lucene 4中搜索int字段?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM