2011-03-13 22 views
1

我想獲得我剛剛添加到Lucene索引的文檔的int docid,以便我可以將其粘貼到Filter中以更新常規查詢。我的文檔具有獨特的外部ID,所以我認爲唯一ID做TermDocs枚舉將返回正確的文檔,像這樣:如何從Lucene 3.0.3獲得可靠的docid?

protected int getDocId(IndexReader reader, String idField, Document doc) throws IOException { 
    String id = doc.get(idField); 
    TermDocs termDocs = reader.termDocs(new Term(idField, id)); 
    int docid = -1; 
    while (termDocs.next()) { 
     docid = termDocs.doc(); 
     Document aDoc = reader.document(docid); 
     String docIdString = aDoc.get(idField); 
     System.out.println(docIdString + ": " + docid); 
    } 
    return docid; 
} 

不幸的是,這個循環和循環,返回相同docIdString和增加docids 。

什麼是推薦的方式來獲取新增文檔的docid,以便我可以在提交文檔後立即在Filter中使用它們?

+0

雖然低於Xodarap的答案是遠遠比上面我的代碼更好,代碼實際工作 - 問題是,我不得不重複的外部IDS由於反覆的調試。 –

回答

1

文檔的文檔ID是而不是與您的ID字段中的值相同。文檔ID是內部Lucene標識符,您可能不應該訪問它。你的領域只是一個領域 - 你可以稱它爲「ID」,但Lucene不會對它做任何特殊的事情。

你爲什麼要手動更新過濾器?當你提交時,合併可能發生等,所以之前的ID將不會與之後的ID相同。 (這只是一個例子,你不應該依賴Lucene ID做任何事情。)因此,你不需要只將一個文檔添加到過濾器,你需要更新整個事情。

要更新緩存過濾器,只需運行「foo」查詢並使用您的過濾器與CachingWrapperFilter


編輯:因爲你的id字段僅僅是一個領域,你爲它做一個搜索,就像您別的:

TopDocs results = searcher.Search(new TermQuery(new Term("MyIDField", Id)), 1); 
int internalId = results.scoreDocs[0].doc; 

但是,就像我說的,我想你想忽略內部ID。所以我就從一個查詢建立一個過濾器:

BooleanQuery filterQuery = new BooleanQuery(); // or get existing query from cache 
filterQuery.Add(new TermQuery(new Term("MyIdField", Id)), BooleanClause.Occur.SHOULD); 
// add more sub queries for each ID you want in the filter here 
Filter myFilter = new CachingWrapperFilter(new QueryWrapperFilter(filterQuery)); 
+0

我有可能數千個常設查詢,我想評估何時添加新文檔。我不想在整個集合上重新運行它們,因爲我應該可以對從其他位置緩存的每個查詢的結果進行增量更新。 CachingWrapperfilter感覺不太對勁:它會緩存舊的結果,但不會緩存新的文檔。似乎博弈應該有足夠的時間來達到我的目的,但也許我誤解了他們的定義。 –

+0

@Gene Golovchinsky:Lucene ID [不持久](http://wiki.apache.org/lucene-java/LuceneFAQ#When_is_it_possible_for_document_IDs_to_change.3F)。你可以嘗試手動告訴他們什麼時候改變?當然。但是你爲了最小的收益正在做很多工作。我建議你確保過濾你的方式是至關重要的 - 如果你只使用緩存過濾器,它將工作99.9999%的時間。不成熟的優化是萬惡之源。 – Xodarap

+0

感謝您的建議!我實際上並沒有試圖堅持docid。我在上面的每個示例代碼中持續使用外部id,並且在任何commit()或optimize()調用之間的特定時間點 - 我想將外部id轉換爲其相應的docid,構建過濾器並使用它。我遇到的問題是我沒有從轉換步驟獲得預期的結果。也許我沒有使用正確的方法將外部id轉換爲docids。 –