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);
Lucene BooleanQuery中的Occur.MUST与Occur.Should的更多相关文章
- 关于Lucene.net 中高亮显示关键词的深究
这几天一直在学习lucene,也写了3篇自己总结的知识点,本以为很容易上手的东西,但是却遇到了一个很棘手的问题,借此,希望可以跟大家探讨一下 问题:使用盘古高亮显示组件后,如搜索“mp3 player ...
- Lucene.NET中Field.Index 和 Field.Store的几种属性的用法
转载自 http://blog.csdn.net/yja886/article/details/6612069 lucene在doc.add(new Field("content" ...
- Lucene BooleanQuery相关算法
BooleanQuery对两种不同查询场景执行不同的算法: 场景1: 所有的子句都必须满足,而且所有的子句里没有嵌套BooleanQuery. 例: a AND b AND c 上面语句表示要同时包含 ...
- lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)
几个注意事项1.建立索引时 插入的顺序(不设置document和字段的boost) 会影响到 查询结果的默认排序,建议:将最新生成的文章 最后建索引 这样 查询结果首先显示的是 最后插入的数据2.Bo ...
- Lucene的多域查询、结果中查询、查询结果分页、高亮查询结果和结果评分
1.针对多个域的一次性查询 1.1.三种方案 使用lucene构造搜索引擎的时候,如果要针对多个域进行一次性查询,一般来说有三种方法: 第一种实现方法是创建多值的全包含域的文本进行索引 ...
- 【转载】关于BooleanQuery在搜索中的用处
我们在搜索中可能会遇到要搜索索引文件中不同字段,不同字段之间就存在了与或非的运算关系,如:这个xx字段中必须存在什么什么关键词,而另一个 XXX字段可以存在或不存在什么什么关键词等等等.这就需要有Bo ...
- Lucene教程(转)
Lucene教程 1 lucene简介1.1 什么是lucene Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿来 ...
- 【转载】Lucene.Net无障碍学习和使用:搜索篇
在上一篇中,我们初步理解了索引的增删改查基本操作.本文着重介绍一下常用的搜索,以及搜索结果的排序和分页.本文的搜索主要是基于前一篇介绍的文本文件的索引,建议下载最后改进的demo对照着看阅读本文,同时 ...
- Lucene.Net+盘古分词->开发自己的搜索引擎
//封装类 using System;using System.Collections.Generic;using System.Linq;using System.Web;using Lucene. ...
随机推荐
- 数据结构---公交线路提示系统05(内附读取表格+迪杰斯特拉算法Java代码)
今天做的最多的事情就是纠错了,通过添加输出语句判断错误来源: 找到错误来源: wb = new XSSFWorkbook(input);//语句创建错误 网上查询发现是jar包的问题: 下图为poi的 ...
- vim配置无插件
其实,vim插件会影响编辑器的启动速度,虽然有些插件影响不大,我依然觉得不够,其实通过简易的状态栏,可以显示必要的信息,能自定义颜色和背景甚至透明就足够了. 一.自定义状态栏其实以下内容可以写在一行上 ...
- Kubernetes Pod 生命周期
一. Pod Hook Kubernetes 为我们提供了生命周期钩子,就是我们所说的Pod Hook,Pod Hook是由kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行.这是 ...
- go 指南学习笔记
1 If for 后面没有小括号.后面的花括号,要在当前行,并且中间有内容,右花括号要单独一行. 因为go会格式化代码,自动插入分号. 2 函数和方法的区别: 方法需要有一个接受者(select ...
- python 图片格式转换png转jpg,如何利用python给图片添加半透明水印
from PIL import Imageim = Image.open(r'd:\test2.png')r, g, b, a = im.split()im = Image.merge("R ...
- vue+websocket demo 实例
vue+websocket demo: <!-- vue + websocket连接demo --> <template> <div class="" ...
- phpstudy apache 服务无法启动
1.找到apache路径 3.打开cmd进入bin文件夹 4.输入 httpd.exe 看报的什么错误即可解决 我的这边是httpd.config 里面配置了个项目文件夹路径,这个文件夹被我删了,导 ...
- word/wps 制作下拉列表
准备: 1.数据页 2.项目名称sheet 3.问题类型sheet 开始制作: 数据 --- 有效性 --- 允许“序列” --- 来源 -- 其他sheet页“单元格”选择范围 回车.确定 即可
- Oracle系列二 基本的SQL SELECT语句
1.查询表中全部数据 示例: SELECT * FROM employees; 说明: SELECT 标识 选择哪些列. FROM 标识从哪个表中选择. * 选择全部 ...
- JSON序列化和反序列化 对decmail 取值问题
地图API返回经纬度:经度: 纬度: lng":114.03483089395202,"lat":22.615589046911805 decmail 接收数据后两位会截 ...