2015-03-13 25 views
4

我想使用Lucene(版本4.10)來處理數百萬條新聞數據。我對Lucene來說很新,所以我想了解它是如何工作的。在每個lucene文檔中,我都會存儲一篇新聞文章。每篇文章當然都有其內容(字段被稱爲「TextContent」)。爲什麼我的短語查詢給我這麼小的結果?

我創建這樣的領域(涉及this計算器問題):

/* Indexed, tokenized, stored. */ 
public static final FieldType TYPE_STORED = new FieldType(); 

static { 
    TYPE_STORED.setIndexed(true); 
    TYPE_STORED.setTokenized(true); 
    TYPE_STORED.setStored(true); 
    TYPE_STORED.setStoreTermVectors(true); 
    TYPE_STORED.setStoreTermVectorPositions(true); 
    TYPE_STORED.freeze(); 
} 

doc.add(new Field("TextContent", oneArticle.getTextContent(), TYPE_STORED)); 

我不喜歡這樣,因爲我想有保存以及文本內容項向量(用於創建短語查詢,所以我可以輕鬆地檢索一篇新聞文章的術語矢量,並用其內容查找其他相關文章)。

我現在要搜索一個或多個單詞(與布爾條款合併Occur.SHOULD或必須)

我的代碼看起來像這樣(的話簡直是包含所有條件來搜索列表)

IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(PATH_TO_INDEX))); 
IndexSearcher searcher = new IndexSearcher(reader); 

BooleanQuery booleanQuery = new BooleanQuery(); 

//words is simply a List<String> containing all terms to search for 
for (String word : words) { 
    PhraseQuery query = new PhraseQuery(); 
    query.add(new Term("TextContent", word)); 
    booleanQuery.add(query, BooleanClause.Occur.SHOULD); 
} 

//collects the results via scoring them using a Similarity Function 
TopScoreDocCollector collector = TopScoreDocCollector.create(reader.numDocs(), true); 
searcher.search(booleanQuery, collector); 
ScoreDoc[] hits = collector.topDocs().scoreDocs; 

System.out.println(hits.length); 

for(int i = 0; i < 10; i++){ 
    int id = hits[i].doc; 
    Document d = searcher.doc(id); 

    System.out.println(d.get("TextContent")); 
} 

我不時得到結果,但還不夠,只有非常流行的搜索條件(例如,「足球」作爲搜索條件爲我提供15000篇文章,同時有數百萬篇新聞文章)。

當我搜索我的textContent字段包含的不太流行的術語時,我得到0個結果。比如我與的TextContent啓動文件:

「桑尼·威廉姆斯將與前所有黑人隊長團聚塔納 了Umaga [..] 29歲的雙橄欖球國際[...]。 「

如果我知道在我的列表單詞中只添加單詞」橄欖球「,我會得到4125個結果,前10名還有我剛纔引用的文章。如果我只是添加單詞「威廉姆斯」(作爲這個橄欖球球員的名字 - 請參閱上面的報價),我得到0個結果。

我不明白這種行爲。我在猜測它必須處理如何在我的Lucene索引中創建「TextContent」字段這一事實。正在進行的谷歌研究將我引向了其他一些計算器問題(例如herehere)。與我的問題不同的是,我不時得到結果,但僅限於非常流行的術語。

你能告訴我我做錯了什麼嗎?你能告訴我如何改變我的TextContent Field/FieldType來提供更好的結果嗎?或者,我應該如何改變我的疑問?

非常感謝每一個答案,並認爲你與我分享。

更新:全新知識ARRIVED

this計算器的問題,我得到了主意,試圖「威廉姆斯」,而不是「威廉姆斯」(全部小寫)。從其中一個答案的報價是:

爲什麼你沒有得到你的文件後面的原因是,雖然 索引你使用StandardAnalyzer,令牌轉換爲小寫 並刪除停用詞。

這工作。如果我寫下所有的小寫,我會得到結果。我還檢查了我的索引與盧克,發現我的術語向量中的所有術語都轉換爲小寫。我現在將在這裏留下這個更新並給出更多潛在答案的空間(可能還是有些錯誤/需要改進才能獲得更好的結果)。如果沒有答案傳入,我將在以後發佈這個答案。

回答

0

聽起來像你找到了問題的原因。處理這個問題的另一個選項是,使用QueryParser來構建查詢時,可以應用相同的分析器。如果你是一個用戶得到一個詞組輸入,然後以某種方式獲取變量words解析它,那麼這可能是一個更容易和更強大的處理它的方式:

QueryParser parser = new QueryParser("TextContent", new StandardAnalyzer()); 
//if you are actually looking for a phrase 
Query queryPhrase = parser.parse("\"" + inputPhrase + "\""); 
//if instead you want independant term queries 
Query queryTerms = parser.parse(inputPhrase); 

另一個請注意,構建僅有一個詞的PhraseQuery沒有多大意義。我不知道以下哪些你正在尋找有:

for (String word : words) { 
    TermQuery query = new TermQuery(new Term("TextContent", word)); 
    booleanQuery.add(query, BooleanClause.Occur.SHOULD); 
} 

或者:

PhraseQuery query = new PhraseQuery(); 
for (String word : words) { 
    query.add(new Term("TextContent", word)); 
} 
booleanQuery.add(query, BooleanClause.Occur.SHOULD); 
相關問題