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);

 
 
标签: luceneBooleanQuery

Lucene BooleanQuery中的Occur.MUST与Occur.Should的更多相关文章

  1. 关于Lucene.net 中高亮显示关键词的深究

    这几天一直在学习lucene,也写了3篇自己总结的知识点,本以为很容易上手的东西,但是却遇到了一个很棘手的问题,借此,希望可以跟大家探讨一下 问题:使用盘古高亮显示组件后,如搜索“mp3 player ...

  2. Lucene.NET中Field.Index 和 Field.Store的几种属性的用法

    转载自 http://blog.csdn.net/yja886/article/details/6612069 lucene在doc.add(new Field("content" ...

  3. Lucene BooleanQuery相关算法

    BooleanQuery对两种不同查询场景执行不同的算法: 场景1: 所有的子句都必须满足,而且所有的子句里没有嵌套BooleanQuery. 例: a AND b AND c 上面语句表示要同时包含 ...

  4. lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)

    几个注意事项1.建立索引时 插入的顺序(不设置document和字段的boost) 会影响到 查询结果的默认排序,建议:将最新生成的文章 最后建索引 这样 查询结果首先显示的是 最后插入的数据2.Bo ...

  5. Lucene的多域查询、结果中查询、查询结果分页、高亮查询结果和结果评分

    1.针对多个域的一次性查询 1.1.三种方案     使用lucene构造搜索引擎的时候,如果要针对多个域进行一次性查询,一般来说有三种方法:     第一种实现方法是创建多值的全包含域的文本进行索引 ...

  6. 【转载】关于BooleanQuery在搜索中的用处

    我们在搜索中可能会遇到要搜索索引文件中不同字段,不同字段之间就存在了与或非的运算关系,如:这个xx字段中必须存在什么什么关键词,而另一个 XXX字段可以存在或不存在什么什么关键词等等等.这就需要有Bo ...

  7. Lucene教程(转)

    Lucene教程 1 lucene简介1.1 什么是lucene    Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿来 ...

  8. 【转载】Lucene.Net无障碍学习和使用:搜索篇

    在上一篇中,我们初步理解了索引的增删改查基本操作.本文着重介绍一下常用的搜索,以及搜索结果的排序和分页.本文的搜索主要是基于前一篇介绍的文本文件的索引,建议下载最后改进的demo对照着看阅读本文,同时 ...

  9. Lucene.Net+盘古分词->开发自己的搜索引擎

    //封装类 using System;using System.Collections.Generic;using System.Linq;using System.Web;using Lucene. ...

随机推荐

  1. GoCN每日新闻(2019-10-16)

    GoCN每日新闻(2019-10-16) GoCN每日新闻(2019-10-16) 1. 持续的性能分析与优化 https://medium.com/@tvii/continuous-profilin ...

  2. 18年今日头条笔试第一题题解:球迷(fans)

    其实本题是加强版,原数据是100*100的,老师为了尊重我们的智商加成了3000*3000并进行了字符串处理…… 上原题~ 球迷 [问题描述] 一个球场C的球迷看台可容纳M*N个球迷.官方想统计一共有 ...

  3. python项目总结--学生选课

    题目要求: 根据业务需求,现要对慕课学院(1)班的所有学员进行选修课程分配,使得每一名学生都可以选修到一门课程.具体要求如下: 1.自定义学生信息.课程信息.教师信息三者的具体描述 2.自定义exam ...

  4. GridLayout: GridLayout中Spec属性

    如果想要让GridLayout中的子元素能够平均分配,就需要用到 android:layout_columnWeight="1" android:layout_rowWeight= ...

  5. npm install Error: EACCES: permission denied, mkdir

    今天研究Electron的时候,全局安装运行 npm install electron -g时侯,报下面的错误: Error: EACCES: permission denied, mkdir '/U ...

  6. hive时间戳转换&UDF更新

    from_unixtime 时间戳转换,如果带毫秒数的,除以1000. # ) ,'yyyy/MM/dd HH:mm:ss') as dt; reload function 今天碰到udf发布后,有时 ...

  7. Delphi ADOConnection连接

    unit Unit_DM; interface usesSysUtils, Classes, DB, ADODB,inifiles,windows,forms,controls; typeTDM = ...

  8. 取消Windows server 2008关机提示备注的方法

    打开“开始”-“运行”,在“打开”一栏中输入“gpedit.msc”命令打开组策略编辑器,依次展开“计算机配置”→“管理模板”→“系统”,双击右侧窗口出现的“显示‘关闭事件跟踪程序’”,将“未配置”改 ...

  9. [LeetCode] 680. Valid Palindrome II 验证回文字符串 II

    Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...

  10. Java之安装JDK

    因为Java程序必须运行在JVM只是,所以我们第一件事情就是安装JDK 从Oracle官网下载最新稳定版JDK 一,Linux系统CentOS安装JDK 下载rpm安装包 安装 rpm -ivh jd ...