zoukankan      html  css  js  c++  java
  • 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);

  • 相关阅读:
    每日一问6:short、int、long以及long long的区别
    每日一问5 什么是类型安全?
    每日一问4: ++i和i++的区别
    每日一问3: C++中extern关键字的作用
    C++中如何判断int型是否溢出
    C++中的POD型别
    Java多线程之一:进程与线程
    设计模式2-单例模式
    Maven学习-编译遇到‘src/checkstyle/checkstyle-suppressions.xml‘
    任意用户登录系统时,显示警示提醒信息 “hi dangerous!”
  • 原文地址:https://www.cnblogs.com/weipeng/p/2455079.html
Copyright © 2011-2022 走看看