几个注意事项
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注释里是这样说的:

  1. public class TermQuery
  2. extends Query
  3. A Query that matches documents containing a term. This may be combined with other terms with a BooleanQuery.

那什么又是Term呢?还是看看官方给的解释吧

  1. public final class Term
  2. extends Object
  3. implements Comparable<Term>
  4. 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的,示例代码如下:

  1. Query query = new TermQuery(new Term(fieldName,queryString));

当然你也可以通过QueryParser类来创建我们的Query对象,如:

  1. QueryParser parser = new QueryParser(fieldName, new AnsjAnalyzer());
  2. 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 的区别)的更多相关文章

  1. 微信小程序开发项目过程中的一个要注意事项

    在微信小程序开发过程中,有时候会用到常用的一些特殊字符如:‘<’.‘>’.‘&’.‘空格’等,微信小程序同样支持对转义字符的处理, decode属性默认为false,不会解析我们的 ...

  2. 理解Lucene索引与搜索过程中的核心类

    理解索引过程中的核心类 执行简单索引的时候需要用的类有: IndexWriter.ƒDirectory.ƒAnalyzer.ƒDocument.ƒField 1.IndexWriter IndexWr ...

  3. Solr环境搭建过程中遇到的问题

    Solr下载地址:http://www.apache.org/dyn/closer.lua/lucene/solr/6.3.0 Solr搭建步骤转自:http://blog.csdn.net/wbcg ...

  4. Lucene的分析过程

    转自:http://www.open-open.com/lib/view/open1348033848724.html Lucene的分析过程 回顾倒排索引的构建 收集待建索引的原文档(Documen ...

  5. WINDOWS系统下MYSQL安装过程中的注意事项

    1.首先MySQL的安装方式有两种:一种是MSI安装方式,很简单就像安装Windows软件一样.另外一种就是ZIP安装方式.这种相对而言比较麻烦.新手推荐MSI安装方式. 安装方式有以下两种: MSI ...

  6. 【转】SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误

    SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误 最近在VS2013上连接远程数据库时,突然连接不上,在跑MSTest下跑的时候,QTAgent32 crash.换成IIS ...

  7. zabbix 3.0.3 (nginx)安装过程中的问题排错记录

    特殊注明:安装zabbix 2.4.8和2.4.6遇到2个问题,如下:找了很多解决办法,实在无解,只能换版本,尝试换(2.2.2正常 | 3.0.3正常)都正常,最后决定换3.0.3 1.Error ...

  8. C语言调试过程中duplicate symbol错误分析

    说明:在我们调试C语言的过程中,经常会遇到duplicate symbol错误(在Mac平台下利用Xcode集成开发环境).如下图: 一.简单分析一下C语言程序的开发步骤. 由上图我们可以看出C语言由 ...

  9. 测试或运维工作过程中最常用的几个linux命令?

     大家在测试工作过程中,可能会遇到需要你去服务器修改一些配置文件,譬如说某个字段的值是1 则关联老版本,是0则关联新版本,这时候你可能就需要会下vi的命令操作:或者查看session设置的时长,可能需 ...

随机推荐

  1. 【题解】【位操作】【Leetcode】Single Number II

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  2. jsb里出现的 Invalid Native Object的一次bug修复的思考

    Cocos2d: jsb: ERROR: File /Users/dcx_JD/Documents/cocos2d-x-2.2.2/scripting/javascript/bindings/gene ...

  3. SAP 审计

    SAP 权限审计:SA38--- RSUSR002 还有其它事务码待续,,,

  4. SQLITE 时间字段操作函数

    SQLite中的时间日期函数 这是我学习SQLite时做的笔记,参考并翻译了Chris Newman写的<SQLite>中的<Working with Dates and Times ...

  5. php构造函数实例讲解

    PHP官网定义: 复制代码 代码如下: 构造函数是类中的一个特殊函数,当使用 new 操作符创建一个类的实例时,构造函数将会自动调用.当函数与类同名时,这个函数将成为构造函数.如果一个类没有构造函数, ...

  6. Android实现拖动进度条改变图片透明度

    layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  7. ThinkPHP缓存微信公众号access_token

    access_token作为微信的全局票据,在高级接口中需要频繁调用,其有效期为7200秒,即2小时,而微信官方对调用Token的次数有限制(参见接口频率限制说明),获取access_token每日限 ...

  8. Android.mk 文件语法详解 转:http://blog.sina.com.cn/s/blog_602f8770010148ce.html

    0. Android.mk简介: Android.mk文件用来告知NDK Build 系统关于Source的信息. Android.mk将是GNU Makefile的一部分,且将被Build Syst ...

  9. 字符串分割函数 STRTOK & STRTOK_R (转)

    1.一个应用实例 网络上一个比较经典的例子是将字符串切分,存入结构体中.如,现有结构体 typedef struct person{     char name[25];     char sex[1 ...

  10. Sublime Text3快捷方式与使用技巧

    Sublime Text 3 快捷键精华版 Ctrl+Shift+P:  打开命令面板Ctrl+P:  搜索项目中的文件Ctrl+G: 跳转到第几行Ctrl+W: 关闭当前打开文件Ctrl+Shift ...