Lucene BooleanQuery中的Occur.MUST與Occur.Should


1.  多個MUST的組合不必多說,就是交集

2.  MUST和SHOULD的組合。是在MUST搜出來的doc里面,根據SHOULD的query進行打分。也就是說,SHOULD的query不會影響最終的HITS,只會提供打分依據。

3.  SHOULD的組合。如果最終的BooleanQuery只有SHOULD,那么搜出來的doc至少要滿足一個SHOULD的query,也就是說是邏輯OR。

那么在下面這段代碼中,問題就出現了:

代碼的本意是在baseQuery的基礎上和geoQuery做一個交集

public Map<String, Query> buildGeoQuery(Query baseQuery) {
    Map<String, Query> queryMap = new HashMap<String, Query>();
    for(String key : localHashMap.keySet()) {
        List<String> hashValues = localHashMap.get(key);
        BooleanQuery bq = new BooleanQuery();
        bq.add(baseQuery, Occur.MUST);
        if(hashValues.size() == 1) {
            TermQuery hashQuery =  
new TermQuery(new Term(Constants.FIELD_SEARCH_HASH, hashValues.get(0)));
            bq.add(hashQuery, Occur.MUST);
        }
        else if(hashValues.size() > 1) {
            for(String value : hashValues) {
                TermQuery hashQuery = new TermQuery(new Term(Constants.FIELD_SEARCH_HASH, value));
                bq.add(hashQuery, Occur.SHOULD);
            }
        }
        queryMap.put(key, bq);
    }
    return queryMap;
}

在第三個用紅色標注的語句中,本意是對多個geohash query做邏輯OR的操作(使用了should),但是由於最開始的basequery是以MUST關鍵字加入的,那么這些個geohash query只做為打分依據,而不是必須出現的,這樣就會導致有一些額外的doc被搜出來。

正確的做法應該是用一個獨立的GeoQuery來把geohash termquery組合起來,最后將geoQuery和baseQuery用Occur.MUST組合

 

 

 

===============================================================================

 

lucene3.0中BooleanQuery 實現與或的復合搜索 .
BooleanClause用於表示布爾查詢子句關系的類,包 括:BooleanClause.Occur.MUST,BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.SHOULD。 必須包含,不能包含,可以包含三種.有以下6種組合: 
 
1.MUST和MUST:取得連個查詢子句的交集。 
2.MUST和MUST_NOT:表示查詢結果中不能包含MUST_NOT所對應得查詢子句的檢索結果。 
3.SHOULD與MUST_NOT:連用時,功能同MUST和MUST_NOT。
4.SHOULD與MUST連用時,結果為MUST子句的檢索結果,但是SHOULD可影響排序。
5.SHOULD與SHOULD:表示“或”關系,最終檢索結果為所有檢索子句的並集。
6.MUST_NOT和MUST_NOT:無意義,檢索無結果。

 

 

====================================================================================

 

在輸入要搜索的關鍵字時,Lucene是這樣處理的:

+a +b:搜索同時包含a又包含b的結果集

a  b:搜索包含a或包含b的結果集

+a -b:搜索包含a不包含b的結果集

也就是如下結論:

  a & b =>  +a +b

  a || b =>  a  b

  a !b  =>  +a -b

 

那在代碼中該如何來構造這種與或非的關系呢?

一般用BooleanQuery來構造。

//構造BooleanQuery
      QueryParser parser = new QueryParser("content", analyzer);
      BooleanQuery bquery = new BooleanQuery();
      TokenStream ts = analyzer.TokenStream(null, new StringReader(querystring));
      Lucene.Net.Analysis.Token token;
      while ((token = ts.Next()) != null)
      {
        Query query = parser.Parse(token.TermText());
        bquery.Add(query, BooleanClause.Occur.MUST);
      }
      //構造完成

            IndexSearcher searcher = new IndexSearcher("IndexDirectory");
      
      //Query query = parser.Parse(querystring);
      //輸出我們要查看的表達式
      Console.WriteLine(bquery.ToString());
      Hits hits = searcher.Search(bquery);
      for (int i = 0; i < hits.Length(); i++)
      {
        Document doc = hits.Doc(i);
        Console.WriteLine(doc.Get("title"));
      }
    }

其中,bquery.Add(query, BooleanClause.Occur.MUST);MUST構造出“與”的關系

構造“或”關系:bquery.Add(query, BooleanClause.Occur.SHOULD);

構造“非”關系:bquery.Add(query, BooleanClause.Occur.MUST_NOT);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM