博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)
阅读量:5742 次
发布时间:2019-06-18

本文共 6092 字,大约阅读时间需要 20 分钟。

原文:

4.3 表达式

用户搜索,只会输入一个或几个词,也可能是一句话。输入的语句是如何变成搜索条件的上一篇已经略有提及。

4.3.1 观察表达式

在研究表达式之前,一定要知道,任何一个Query都会对于一个表达式。不光可以通过Query构造表达式,还可以通过拼接字符串构造。这里说的观察表达式是指,用Query完成查询语句后,用ToString()方法输出Query的表达式。很简单是吧,呵呵。

4.3.2 表达式的与或非

“与或非”让我想起上学的时候学的门电路 ==#。先动手看看什么是与或非。

 

代码 4.3.2.1 using System; using System.Collections.Generic; using Lucene.Net.Analysis; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using NUnit.Framework; namespace Test {
[TestFixture] public class StandardAnalyzerCaseTest {
/// /// 执行测试的入口 /// [Test] public void SearcherTest() {
Index(); List
list = new List
() { "测试" }; for (int i = 0; i < list.Count; i++) {
Console.WriteLine("搜索词:" + list[i]); Console.WriteLine("结果:"); Searcher(list[i]); Console.WriteLine("-----------------------------------"); } } ///
/// 搜索 /// ///
搜索输入 private void Searcher(string querystring) {
Analyzer analyzer = new StandardAnalyzer(); IndexSearcher searcher = new IndexSearcher("IndexDirectory"); QueryParser parser = new QueryParser("content", analyzer); Query query = parser.Parse(querystring); //输出我们要查看的表达式 Console.WriteLine(query.ToString()); Hits hits = searcher.Search(query); for (int i = 0; i < hits.Length(); i++) {
Document doc = hits.Doc(i); Console.WriteLine(doc.Get("title")); } } ///
/// 索引数据 /// private void Index() {
Analyzer analyzer = new StandardAnalyzer(); IndexWriter writer = new IndexWriter("IndexDirectory", analyzer, true); AddDocument(writer, "测试", @"测定是123123ab阿布"); AddDocument(writer, "测试测", @"测试搜索真的是不是 "); AddDocument(writer, "来测试", @"好好测试山"); AddDocument(writer, "测试系统", @"测试样例"); writer.Optimize(); writer.Close(); } ///
/// 添加文档 /// ///
维护文档管理器 ///
标题 ///
内容 ///
tag ///
tag的boost void AddDocument(IndexWriter writer, string title, string content) {
Document document = new Document(); document.Add(new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED)); document.Add(new Field("content", content, Field.Store.YES, Field.Index.TOKENIZED)); writer.AddDocument(document); } } }

 

先准备好代码4.3.2.1,OK,现在测试。结果输出:

搜索词:测试

结果:
content:"测 试"
测试系统
来测试
测试测
-----------------------------------
第三行,就是表达式。这个表达式不知道是什么意思?输入了“测试”这两个字进行搜索,怎么会变成 “content:"测 试"”呢?可以看出,“测试”中间空了一个空格,还多了一个content。“测试”中间有空格不难理解,是分词器对它进行拆分的结果。至于content,这个需要把目光转到QueryParser类上去,在构造QueryParser类的时候,就加了这么个参数。这个是表面要搜索哪个字段。为了验证这个想法,现在把“测试”换成英文“ab”,把content换成title.

也就是替换以下两句:

List<string> list = new List<string>() { "ab" };         //在方法SearcherTest中

QueryParser parser = new QueryParser("title", analyzer);     //在方法Searcher中

现在再测试一下:

搜索词:ab

结果:
title:ab
-----------------------------------
看到了,果然是这样的。

现在把查询的字段还是换成content,然后把关键字换成“真是”。

搜索词:真是

结果:
content:"真 是"
-----------------------------------
结果出来了,也印证了上面的想法。但是明明有一条记录同时包含这两个字了,为什么没有搜索到呢?是不是加个空格就可以了呢?把“真的”变成“真 的”。再来试试。

搜索词:真 是

结果:
content:真 content:是
测试测
测试
-----------------------------------

真神奇,表达式变掉了,而且只包含一个“是”但是没有“真”的记录也出来了。这表明什么?这表明现在的语句就是或的关系,只要满足包含“是”或者包含“真”就可以搜索到了。

(以上内容前面章节有提到,现在开始进入正式气氛。——)

但是我现在就想要搜索同时包含两个字的记录怎么办呢?嘿嘿,在每个字前面加个“+”号试试。关键词变成“+真 +是”看看结果:

搜索词:+真 +是

结果:
+content:真 +content:是
测试测
-----------------------------------

那现在我要搜索包含“是”但是不包含“真”的结果,怎么办?试试这个语句“-真 +是”。

搜索词:-真 +是

结果:
-content:真 +content:是
测试
-----------------------------------
与或非终于被我们折腾完了。

总结下关系就是:

a & b  =>   +a +b

a || b  =>   a    b
a  !b   =>   +a  -b
4.3.3 如何用Query构造与或非

Lucene.Net框架提供的Query也是可以完成与或非运算的,一般用BooleanQuery来构造。怎么构造?现在对搜索部分代码进行变动,变成4.3.3.1。

代码 4.3.3.1         ///  /// 执行测试的入口 ///          [Test] public void SearcherTest()         {
Index(); List
list = new List
() { "真是" }; for (int i = 0; i < list.Count; i++) {
Console.WriteLine("搜索词:" + list[i]); Console.WriteLine("结果:"); Searcher(list[i]); Console.WriteLine("-----------------------------------"); } } ///
/// 搜索 /// ///
搜索输入 private void Searcher(string querystring) {
Analyzer analyzer = new StandardAnalyzer(); //构造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")); } }

 

测试:

搜索词:真是

结果:
+content:真 +content:是
测试测
-----------------------------------
构造出与的表达式了。把BooleanQuery的Add方法第二个参数换成BooleanClause.Occur.SHOULD,

bquery.Add(query, BooleanClause.Occur.SHOULD);

这个就是或:

搜索词:真是

结果:
content:真 content:是
测试测
测试
-----------------------------------
而换成 bquery.Add(query, BooleanClause.Occur.MUST_NOT);这个就是非了:

搜索词:真是

结果:
-content:真 -content:是
-----------------------------------

4.3.4 其它特使符号

如果形容"+-"为Lucene.Net的运算符的话,那只有这么两个也太单调了。实际上它还有其它运算符。

+-!():^[]{}~*?

上面的字符都是它的运算符号,这么多运算符用起来很方便。但是也就出现另外一个问题。

 

什么问题?下一节再讲。

转载地址:http://wjszx.baihongyu.com/

你可能感兴趣的文章
python分类
查看>>
GitBlit (1)-- 在linux 安装 GitBlit 并运行
查看>>
程序是如何执行的(一)a=a+1
查看>>
18 已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果
查看>>
BZOJ - 3578: GTY的人类基因组计划2
查看>>
爱——无题
查看>>
分布式服务框架原来与实践 读书笔记一
查看>>
【http】post和get请求的区别
查看>>
TFS强制撤销某个工作区的文件签出记录
查看>>
EL表达式无法显示Model中的数据
查看>>
ps6-工具的基础使用
查看>>
灵活运用 SQL SERVER FOR XML PATH
查看>>
linux下使用过的命令总结(未整理完)
查看>>
时间助理 时之助
查看>>
英国征召前黑客组建“网络兵团”
查看>>
Silverlight 2.5D RPG游戏“.NET技术”技巧与特效处理:(十二)魔法系统
查看>>
PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)...
查看>>
pyjamas build AJAX apps in Python (like Google did for Java)
查看>>
LAMP环境搭建1-mysql5.5
查看>>
centos5.9使用RPM包搭建lamp平台
查看>>