2013-03-31 170 views
3

我在Lucene中編寫了一個索引搜索器,它將搜索索引數據庫中的多個字段。Lucene中的多字段查詢處理

其實它需要查詢爲兩個字符串,一個是title,另一個是cityname

現在索引數據庫有三個字段:title, address and city

僅當標題匹配和城市名稱匹配時纔會發生點擊。爲此目的,我寫了使用MultiFieldQuerySearcher與後的幫助下面的搜索代碼:

public void searchdb(String myQuery, String myCity) throws Exception 
{ 
    System.out.println("Searching in the database ..."); 
    String[] fields={"title","address","city"}; 
    MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, fields, new StandardAnalyzer(Version.LUCENE_CURRENT)); 
    parser.setDefaultOperator(QueryParser.Operator.AND); 
    if(!myQuery.toLowerCase().contains(myCity.toLowerCase())) 
    { 
     myQuery="title:"+myQuery+" "+"address:"+myQuery+" "+myCity+" "+"city:"+myCity; 
    } 
    Query query=parser.parse(myQuery); 
    if (query instanceof BooleanQuery) 
    { 
     BooleanClause.Occur[] flags ={BooleanClause.Occur.MUST,BooleanClause.Occur.SHOULD,BooleanClause.Occur.MUST}; 
     BooleanQuery booleanQuery = (BooleanQuery) query; 
     BooleanClause[] clauses = booleanQuery.getClauses(); 
     System.out.println("Query="+booleanQuery.toString()+" and Number of clauses="+clauses.length); 
     for (int i = 0; i < clauses.length; i++) 
     { 
      clauses[i].setOccur(flags[i]); 
     } 
     Directory dir=FSDirectory.open(new File("demoIndex")); 
     IndexSearcher searcher = new IndexSearcher(dir, true); 
     TopDocs hits = searcher.search(booleanQuery, 20); 
     searcher.close(); 
     dir.close(); 
     System.out.println("Number of hits="+hits.totalHits); 
    } 
} 

但運行不正常。

例如,如果查詢是「必勝客」而城市是「孟買」,我只希望在數據庫的標題字段和孟買僅在數據庫的城市字段中搜索「必勝客」。

但它是尋找「必勝客」也可在數據庫作爲語句booleanQuery.toString的輸出城市場()即將爲「+標題:比薩+(標題:小屋城市:小屋) + city:mumbai「。

作爲for循環的結果,它給出索引outOfBound錯誤。

我是Lucene的新手。所以我正在尋求幫助來解決這個問題。

+0

請問你能分享一下你的代碼嗎? – jbakirov

回答

7

僅當我們想在多個字段中搜索相同關鍵字時,我們才使用MultiFieldQueryParser。

要處理您的用例,您已經分別引用city-keyword和title-keyword更簡單。嘗試使用以下代碼。

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); 
// city query 
QueryParser cityQP = new QueryParser(Version.LUCENE_CURRENT, "city", analyzer); 
Query cityQuery = cityQP.parse(myCity); 

// title query 
QueryParser titleQP = new QueryParser(Version.LUCENE_CURRENT, "title", analyzer); 
Query titleQuery = titleQP.parse(myQuery); 

// final query 
BooleanQuery finalQuery = new BooleanQuery(); 
finalQuery.add(cityQuery, Occur.MUST); // MUST implies that the keyword must occur. 
finalQuery.add(titleQuery, Occur.MUST); // Using all "MUST" occurs is equivalent to "AND" operator. 
+0

謝謝,先生:) – Joy

+0

但先生有一個問題。在我的索引中,有一個條目的標題是「必勝客」,城市是「孟買」。當我查詢標題爲「比薩」和城市「MUmbai」的索引時,命中數量爲0.但根據我的理解,這應該是一個,因爲這兩個術語都出現在其相應的字段中。你能解釋一下嗎? – Joy

+0

1)確保在索引和查詢時使用相同的分析器.--- 2)請將最終查詢打印到輸出並粘貼到此處.--- 3)使用Luke檢查您的索引。它使用簡單。它是一個用於探索和檢查Lucene索引的GUI工具。請使用Luke檢查索引是否包含您所期望的內容.---順便說一句,請不要再使用「先生」。:) – phani