Lucene BooleanQuery中的Occur.MUST與Occur.Should

 

1.  多個MUST的組合沒必要多說,就是交集html

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

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

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

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

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;
}blog

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

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

 

 

 

===============================================================================ip

 

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:無心義,檢索無結果。get

 

 

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

 

在輸入要搜索的關鍵字時,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);

 
 
標籤:  luceneBooleanQuery
相關文章
相關標籤/搜索