lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)
几个注意事项
1.建立索引时 插入的顺序(不设置document和字段的boost) 会影响到 查询结果的默认排序,建议:将最新生成的文章 最后建索引 这样 查询结果首先显示的是 最后插入的数据
2.BooleanQuery的多条件查询 一定是多个 must的组合,否则就不是 and关系了,如下代码:
3.查询时候亦可对 结果进行权重排序,通过设置Query的Boost属性即可,如下述代码所示
4.查询时,通常首先对关键词进行分词处理之后,再设置为多个分词的 查询条件,如下代码这一部分 foreach (var wordInfo in words)
5.建立索引时 分词被索引时 不区分大小写,也就是 你在查询的时候 必须按照 指定的大小写 查询,如果想解决这个大小写问题:建立索引时 多建一个统一小写的filed吧,查询时 也用小写后的关键词进行分词
//单字段查询
//QueryParser qp = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "title", analyzer);
//Query mQuery = qp.Parse(keyword); //2008年底 //多字段查询一
//var fields = new Dictionary<string, string>() { { "title", keyword }, { "body", keyword } };
//var fieldsOccur = new Dictionary<string, Occur>() { { "title", Occur.SHOULD }, { "body", Occur.SHOULD } };
//if (!string.IsNullOrEmpty(lang))
//{
// fields.Add("lang",lang);
// fieldsOccur.Add("lang", Occur.MUST);
//}
//Query mQuery = MultiFieldQueryParser.Parse(Version.LUCENE_30, fields.Select(x => x.Value).ToArray(), fields.Select(x => x.Key).ToArray(), fieldsOccur.Select(x=>x.Value).ToArray(), analyzer); //多字段查询二[弊端 只支持单个关键词输入]
//MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, new string[] { "lang", "title", "body" }, analyzer, new Dictionary<string, float>() { { "lang", 3 }, { "title", 2 }, { "body", 1 } });
//parser.DefaultOperator = QueryParser.Operator.AND;
//Query mQuery = parser.Parse(keyword); //多字段查询三
Query query1 = null;
var mQuery = new BooleanQuery();
//分类查询
query1 = new TermQuery(new Term("type", type));
mQuery.Add(query1, Occur.MUST);
//通配符查询
if (string.IsNullOrEmpty(lang)) lang = "*";
query1 = new WildcardQuery(new Term("lang", lang));
mQuery.Add(query1, Occur.MUST);
//范围查询
var beginTime = Convert.ToInt64(TimeHelper.ToUnixTimeStamp(DateTime.Now.AddYears(-)));
var endTime = Convert.ToInt64(TimeHelper.ToUnixTimeStamp(DateTime.Now.AddYears()));
query1 = NumericRangeQuery.NewLongRange("time", , beginTime, endTime, true, true);
mQuery.Add(query1, Occur.MUST);
var keyQuery = new BooleanQuery();
#region 方法一 (查询结果较精准,最优结果在前面,结果较多)
foreach (var wordInfo in words)
{
var word = wordInfo.Word;
//标题查询
query1 = new TermQuery(new Term("title", word)) { Boost = };
keyQuery.Add(query1, Occur.SHOULD);
//内容查询
query1 = new TermQuery(new Term("body", word)) { Boost = };
keyQuery.Add(query1, Occur.SHOULD); //支持小写 TermQuery不会对你提供的fieldValue做任何处理,所以部分可能查不出来,这里让其支持小写 以便能查出结果
word = word.ToLower();
//标题查询
query1 = new TermQuery(new Term("title", word)) { Boost = };
keyQuery.Add(query1, Occur.SHOULD);
//内容查询
query1 = new TermQuery(new Term("body", word)) { Boost = };
keyQuery.Add(query1, Occur.SHOULD); }
#endregion
#region 方法二 查询结果较精准,结果较少
//query1 = new QueryParser(Version.LUCENE_30, "title", analyzer).Parse(keyword);
//query1.Boost = 200;
//keyQuery.Add(query1, Occur.SHOULD);
//query1 = new QueryParser(Version.LUCENE_30, "body", analyzer).Parse(keyword);
//query1.Boost = 2;
//keyQuery.Add(query1, Occur.SHOULD);
#endregion #region 方法三 查询结果较精准,结果较少
//MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, new string[] { "title", "body" }, analyzer, new Dictionary<string, float>() { { "title", 200 }, { "body", 2 } });
////parser.DefaultOperator = QueryParser.Operator.OR;
//query1 = parser.Parse(keyword);
//keyQuery.Add(query1, Occur.SHOULD);
#endregion
#region 方法四 查询结果较精准,结果较少 用时超级长 6000条数据12秒(不准确,单元测试的速度 不能为准,实际很快的)
//MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, new string[] { "title", "body" }, analyzer, new Dictionary<string, float>() { { "title", 200 }, { "body", 2 } });
////parser.DefaultOperator = QueryParser.Operator.OR;
//query1 = parser.Parse(keyword);
//mQuery.Add(query1, Occur.MUST);
#endregion if(keyQuery.Any())mQuery.Add(keyQuery,Occur.MUST);
TopDocs tds = searcher.Search(mQuery, );
下面转自:http://iamyida.iteye.com/blog/2194651
首先来学习用下TermQuery,这是最简单的一个Query实现,即查询索引文档中是否包含了指定的Term,Lucene官方API注释里是这样说的:
- public class TermQuery
 - extends Query
 - A Query that matches documents containing a term. This may be combined with other terms with a BooleanQuery.
 
那什么又是Term呢?还是看看官方给的解释吧
- public final class Term
 - extends Object
 - implements Comparable<Term>
 - A Term represents a word from text. This is the unit of search. It is composed of two elements, the text of the word, as a string, and the name of the field that the text occurred in. Note that terms may represent more than words from text fields, but also things like dates, email addresses, urls, etc.
 
一个Term表示着一个来自文本中的一个单词(因为老外眼里只有单词,没有中文,在中文里word可以理解为一个词语),它是一个搜索单元,它有两部分组成,单词文本和域的名称,后面着重提醒了我们,term不仅仅是文本中单词,还可以是日期,email地址,url链接等等。一句话,Term就是分词过后的一个个词组。
使用的时候new TermQuery(Term term)即可,Term对象的构造器有两个参数,fieldName和fieldValue,如:
new Term("title","Java");即表示在title域里查询包含Java的,示例代码如下:
- Query query = new TermQuery(new Term(fieldName,queryString));
 
当然你也可以通过QueryParser类来创建我们的Query对象,如:
- QueryParser parser = new QueryParser(fieldName, new AnsjAnalyzer());
 - Query query = parser.parse(queryString);
 
但两者还是有点小小区别的,QueryParser会经过分词器,会使用分词器把我们的queryString(用户输入的查询关键字)进行分词,我们都知道分词器一般都会先把文本先全部转成小写然后去掉停用词等等一系列操作,而TermQuery则不会,而是直接根据用户提供的fieldValue去分词后的Term里查找的,我们知道分词后索引里存储的Term的value肯定都是小写的,如果我们提供的fieldVlue是大写的,肯定是查询不到的,这是大家比较容易忽略的,举个例子吧,比如你的文本里包含了“I服了U”这个网络词汇的,默认肯定是不会把它当成一个词语,如果使用了ansj分词器并把这个词语配置到自定义词典里,如:

那么分词后我们索引里的term中存储的应该是i服了u,而不是I服了U,所以如果你们使用I服了U作为搜索关键字来搜索,是搜不到任何结果的,这时你就蒙圈了,我不是已经配置了自定义词典了吗?为什么找不到?为了避免你们犯这种错误,特此提醒,TermQuery不会对你提供的fieldValue做任何处理,而QueryParser会,这也是为什么QueryParser构建的时候需要用户提供Analyzer对象而TermQuery不需要的原因。
TermQuery使用起来很简单,使用时候该注意的问题我也说过了,就说这么多,打完收工!希望对你们学习Lucene有所帮助。
lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)的更多相关文章
- 微信小程序开发项目过程中的一个要注意事项
		
在微信小程序开发过程中,有时候会用到常用的一些特殊字符如:‘<’.‘>’.‘&’.‘空格’等,微信小程序同样支持对转义字符的处理, decode属性默认为false,不会解析我们的 ...
 - 理解Lucene索引与搜索过程中的核心类
		
理解索引过程中的核心类 执行简单索引的时候需要用的类有: IndexWriter.Directory.Analyzer.Document.Field 1.IndexWriter IndexWr ...
 - Solr环境搭建过程中遇到的问题
		
Solr下载地址:http://www.apache.org/dyn/closer.lua/lucene/solr/6.3.0 Solr搭建步骤转自:http://blog.csdn.net/wbcg ...
 - Lucene的分析过程
		
转自:http://www.open-open.com/lib/view/open1348033848724.html Lucene的分析过程 回顾倒排索引的构建 收集待建索引的原文档(Documen ...
 - WINDOWS系统下MYSQL安装过程中的注意事项
		
1.首先MySQL的安装方式有两种:一种是MSI安装方式,很简单就像安装Windows软件一样.另外一种就是ZIP安装方式.这种相对而言比较麻烦.新手推荐MSI安装方式. 安装方式有以下两种: MSI ...
 - 【转】SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误
		
SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误 最近在VS2013上连接远程数据库时,突然连接不上,在跑MSTest下跑的时候,QTAgent32 crash.换成IIS ...
 - zabbix 3.0.3 (nginx)安装过程中的问题排错记录
		
特殊注明:安装zabbix 2.4.8和2.4.6遇到2个问题,如下:找了很多解决办法,实在无解,只能换版本,尝试换(2.2.2正常 | 3.0.3正常)都正常,最后决定换3.0.3 1.Error ...
 - C语言调试过程中duplicate symbol错误分析
		
说明:在我们调试C语言的过程中,经常会遇到duplicate symbol错误(在Mac平台下利用Xcode集成开发环境).如下图: 一.简单分析一下C语言程序的开发步骤. 由上图我们可以看出C语言由 ...
 - 测试或运维工作过程中最常用的几个linux命令?
		
大家在测试工作过程中,可能会遇到需要你去服务器修改一些配置文件,譬如说某个字段的值是1 则关联老版本,是0则关联新版本,这时候你可能就需要会下vi的命令操作:或者查看session设置的时长,可能需 ...
 
随机推荐
- 设置mysql远程连接root权限
			
在远程连接mysql的时候应该都碰到过,root用户无法远程连接mysql,只可以本地连,对外拒绝连接.需要建立一个允许远程登录的数据库帐户,这样才可以进行在远程操作数据库.方法如下:默认情况下MYS ...
 - 十日谈  (share)
			
@拔赤 一直想写这篇“十日谈”,聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是“初级”前端开发工程师 ...
 - ABAP 使用的字符类型
			
1.ABAP基本数据类型 类型 描述 属性 C 字符类型 默认长度1,最大长度不限N 数字类 ...
 - 彻底弄懂css中单位px和em,rem的区别  转的自己看
			
国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem,那么三者有什么区别,又各自有什么优劣呢? PX特点 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的 ...
 - 启动tomcat不出现命令窗口
			
有个软件要安装在U盘中,B/S结构,用tomcat做应用服务器,客户要求tomcat不能注册为系统服务,启动时tomcat启动时不能出现命令行窗口,怎么实现? 根据你的问题描述,猜测你的部署系统是Wi ...
 - Chrome A标签的迁移错误:【Error loading page】
			
在IE中经常使用A标签用来迁移,正确的写法是 <a href="001.html"></a>即可,不过在chrome上面可能会引发错误无法迁移. 比如用下面 ...
 - HTTP详解(1)-工作原理
			
出处 http://blog.csdn.net/hguisu/article/details/8680808#t0 1. HTTP简介 HTTP协议(HyperText Transfer Protoc ...
 - Oracle 删除用户和表空间
			
版权声明:本文为博主原创文章,未经博主允许不得转载. Oracle 使用时间长了, 新增了许多user 和tablespace. 需要清理一下 对于单个user和tablespace 来说, 可以使用 ...
 - CDH hive的安装
			
tar zxvf 解压包 配置环境变量 export HIVE_HOME=/usr/local/soft/hiveexport PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HO ...
 - Android多线程入门学习
			
(1)进程间通信交换信息的一种方式--使用handler: (2)在主线程中new一个Handler对象,并重写他的handlerMessage(Message msg)方法: (3)Message中 ...