2014-04-03 59 views
0

如果整個查詢不返回任何結果,我需要確定Lucene BooleanQuery的哪個部分失敗。我使用BooleanQuery組成和PhraseQuery。每個都通過Occur.MUST添加到查詢中。確定哪個參數在Lucene BooleanQuery中失敗?

如果我沒有得到任何查詢結果,有沒有辦法告訴哪部分查詢無法匹配任何東西?我是否需要單獨運行查詢並比較結果以獲得失敗的結果?

編輯 - 添加了PhraseQuery的代碼。

if(row.getPropertykey_tx() != null && !row.getPropertykey_tx().trim().isEmpty()){ 
    PhraseQuery pQuery = new PhraseQuery(); 
    String[] words = row.getPropertykey_tx().trim().split(" "); 
    for(String word : words){ 
     pQuery.add(new Term(TitleRecordColumns.SA_SITE_ADDR.toString(), word)); 
    } 
    pQuery.setSlop(2); 

    topBQuery.add(pQuery, BooleanClause.Occur.MUST); 
} 

回答

1

對我而言,運行查詢的單個部分可能是最簡單的方法。

另一個可用的工具是獲得Explaination。您可以撥打IndexSearcher.explain以獲取針對特定文檔的查詢的評分解釋。如果您可以提供您認爲應與查詢匹配的文檔的docid,則可以分析Explanation.toString(或toHtml,如果您願意)以確定哪些子查詢與它不匹配。


如果你想自動保持的其中BooleanQuery的條款不產生結果的記錄,我相信你會需要independantly運行每個查詢。如果你不再有機會獲得用於創建它的子查詢,你可以得到它的條款改爲:

findTroublesomeQuery(BooleanQuery query) { 
    for (BooleanClause clause : query.clauses()) { 
     Query subquery = clause.getQuery() 
     TopDocs docs = searchHoweverYouDo(subquery); 
     if (doc.totalSize == 0) { 
      //If you want to dig down recursively... 
      if (subquery instanceof BooleanQuery) 
       findTroublesomeQuery(query); 
      else 
       log(query); //Or do whatever you want to keep track of it. 
     } 
    } 
} 

DisjunctionMaxQuery是一種常用的查詢包裹多個子查詢一樣,所以可能是值得考慮這個種方法。

+0

我添加了代碼來創建我的PhraseQuery。該指數約爲1300萬條記錄。我不知道任何一個條目的具體文件ID。我想要做的是記錄任何不會產生結果的東西,以便我可以稍後分析。 – Cuthbert

+0

看起來你正在接近'PhraseQuery'的方式,儘管如此,我仍然會關注分析。如果該字段使用「StandardAnalyzer」,例如標點符號,大寫字符等可能會產生問題,如果其他地方沒有進一步標準化。 – femtoRgon

+0

它確實使用'StandardAnalyzer',但我在我的代碼中刪除了其他地方的標點符號。所以我覺得我沒事。謝謝你!您提供的代碼段非常有幫助。 – Cuthbert