Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

原文:Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了。

代码 4.3.4.1
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser("title", analyzer);
Query query = parser.Parse(@":");
Console.WriteLine("--" + query.ToString() + "--");
Console.ReadKey();

 

运行代码4.3.4.1,发现会引发错误。

未处理 Lucene.Net.QueryParsers.ParseException
  Message="Cannot parse ':': Encountered \":\" at line 1, column 0.\nWas expecting one of:\n    <NOT> ...\n    \"+\" ...\n    \"-\" ...\n    \"(\" ...\n    \"*\" ...\n    <QUOTED> ...\n    <TERM> ...\n    <PREFIXTERM> ...\n    <WILDTERM> ...\n    \"[\" ...\n    \"{\" ...\n    <NUMBER> ...\n    "
  Source="Lucene.Net"
  StackTrace:
       在 Lucene.Net.QueryParsers.QueryParser.Parse(String query) 位置 D:\Lucene.Net\Lucene.Net\QueryParser\QueryParser.cs:行号 186
       在 TestLucene.Program.Main(String[] args) 位置 D:\TestLucene\TestLucene\TestLucene\Program.cs:行号 23
       在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       在 System.Threading.ThreadHelper.ThreadStart()
  InnerException:

 

":"符号死特殊符号,只有这样一个符号是无法解析的。如果实在需要搜索这个符号,那么给它加上一个"\"。代码就变成了4.3.4.2.

 

代码 4.3.4.2
Analyzer analyzer = new SimpleAnalyzer();
QueryParser parser = new QueryParser("title", analyzer);
Query query = parser.Parse(@"\:");
Console.WriteLine("--" + query.ToString() + "--");
Console.ReadKey();

 

运行输出:

----

发现"\:"并没有预想的那样,输出一个":"出来。大多数时候可能并不会引人注意,实际上确实有很多人会认为这个符号可能是在Lucene内部被替换掉了。那么实际情况呢?如果不看Lucene的代码,盲目尝试的话,很难尝试出来,这里就不细说了。

把代码改成4.3.4.3

代码 4.3.4.3
Analyzer analyzer = new WhitespaceAnalyzer();
QueryParser parser = new QueryParser("title", analyzer);
Query query = parser.Parse(@"\:");
Console.WriteLine("--" + query.ToString() + "--");
Console.ReadKey();

 

换了个分词器,效果就不一样了,嘿嘿。4.3.4.3输出内容就变成了:

--title::--

为什么会这样呢?来分析下分词输出的结果。先构造一个测试方法:

代码 4.3.4.4
void AnalyzerConsole(Analyzer analyzer)
{
    TokenStream stream = analyzer.TokenStream("title", new StringReader(@"\:"));
    Lucene.Net.Analysis.Token token;
    Console.WriteLine(analyzer.GetType().Name);
    while ((token = stream.Next()) != null)
    {
        Console.WriteLine(token.TermText());
    }
}

 

然后调用代码:

 

代码 4.3.4.5
AnalyzerConsole(new StandardAnalyzer());
AnalyzerConsole(new WhitespaceAnalyzer());
AnalyzerConsole(new StopAnalyzer());
AnalyzerConsole(new SimpleAnalyzer());
Console.ReadKey();

 

共测试了4个内置分词器。得出的结果是,除了WhitespaceAnalyzer,其它三个分词都把"\:"替换掉了。

输出的结果:
StandardAnalyzer
WhitespaceAnalyzer
\:
StopAnalyzer
SimpleAnalyzer

看来,特殊符号的问题,还是跟分词器息息相关的。

这个就说明一个问题,在使用多条件或者构造搜索表单式的时候尽量使用内置类,而尽量不要手动构造查询字符串。

时间: 2024-09-19 08:15:52

Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)的相关文章

Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此,搜索和索引一般是分开部署.简单地说,就是一个应用程序(桌面程序)来索引,一个WEB程序来实现搜索.当然,为了测试的时候简单,这里还是使用NUnit的方式运行.搜索讲完后,将会简单介绍单机搜索引擎如何部署. 4.1 搜索与什么有关 搜索与什么有关呢?即使没有看过前面的文章,那么现在来随便猜一猜. 首

Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察表达式在研究表达式之前,一定要知道,任何一个Query都会对于一个表达式.不光可以通过Query构造表达式,还可以通过拼接字符串构造.这里说的观察表达式是指,用Query完成查询语句后,用ToString()方法输出Query的表达式.很简单是吧,呵呵. 4.3.2 表达式的与或非"与或非"

Lucene.Net 2.3.1开发介绍 —— 二、分词(四)

原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(四) 2.1.2 可以使用的内置分词   简单的分词方式并不能满足需求.前文说过Lucene.Net内置分词中StandardAnalyzer分词还算比较实用(见1.1.2小节).StandardAnalyzer为什么能满足我们的部分需求,而它又有哪些不足呢?看分词的好坏还是要从效果说起.简单的说,在中英文混合的情况下,StandardAnalyzer会把英文按空格拆,而中文则按单字拆.因为中文是按单字拆,所以对分词的准确性起到了干

Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响   搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个这个结果是怎么得出来的?这个顺序又是怎么排的呢?这两个问题不是本节讨论的重点,但是这两个问题却关系到本节要讨论的,索引对结果的影响问题.在不使用字段排序的情况下,Lucene.Net默认是按文档的得分来排序的,这个公式看着很复杂,感觉像是大学时高数书上的那些个公式,其实说清楚了也简单. 关于文档

Lucene.Net 2.3.1开发介绍 —— 三、索引(五)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(五) 话接上篇,继续来说权重对排序的影响.从上面的4个测试,只能说是有个直观的理解了."哦,是!调整权重是能影响排序了,但是好像没办法来分析到底怎么调啊!".似乎是这样,现在需要把问题放大,加大索引的内容.到博客园新闻区,用zzk找了4篇内容包含"测试"的文章.代码变成 2.1.5 代码2.1.5  1using System;  2using System.Collections.Generic;  

Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果  索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果. 代码 3.1   Code 1/**//// <summary> 2/// 索引数据 3/// </summary> 4private void Index() 5{ 6    Analyzer analyzer = ne

Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的基础,Directory是索引建立中或者建立好存储的介质,Document和Field类是逻辑结构的核心,IndexWriter是操作的核心.其他类的使用都被隐藏掉了,这也是为什么Lucene.Net使用这么方便的原因.   2.1 Analyzer 前面已经对Analyzer进行了很详细的讲解,A

Lucene.Net 2.3.1开发介绍 —— 二、分词(五)

原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(五) 2.1.3 二元分词   上一节通过变换查询表达式满足了需求,但是在实际应用中,如果那样查询,会出现另外一个问题,因为,那样搜索,是只要出现这个字,不管它出现在什么位置.这就产生了上一小节开头讲的,对准确性产生了极大干扰.比如,如果有一段这样的话:"这是一个英雄!他有无法用词汇形容的孤单,但是他并没有用言语来表达."这句话包含了"英 语 单 词"这四个字,但是却和"英语单词"一

Lucene.Net 2.3.1开发介绍 —— 简介

原文:Lucene.Net 2.3.1开发介绍 -- 简介          Lucene.Net是Lucene在dot net平台上的移植版本.它的功能与Lucene一样,都是用来提供一组API,让我们能快速开发自己的搜索引擎,当然,是全文搜索.它不是一个程序,拿到它并不能立刻运行,你必须自己实现逻辑过程.这是一个和.Net Framework一样的框架.Lucene是用Java写的,尔后衍生出Nutch,接着又衍生出Hadoop.这些可以说和Lucene没有内在联系,但是它们可以扩充Luce