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

时间:2021-04-12 03:09:48

2.1.2 可以使用的内置分词

 

简单的分词方式并不能满足需求。前文说过Lucene.Net内置分词中StandardAnalyzer分词还算比较实用(见1.1.2小节)。StandardAnalyzer为什么能满足我们的部分需求,而它又有哪些不足呢?看分词的好坏还是要从效果说起。简单的说,在中英文混合的情况下,StandardAnalyzer会把英文按空格拆,而中文则按单字拆。因为中文是按单字拆,所以对分词的准确性起到了干扰,搜索结果就会不准确,至少理论上是这样的。但是实际上StandardAnalyzer分词器并没有我们想的那么差劲。因为搜索不光与分词有关,还和查询的逻辑有关,这个会在第四章讲搜索的时候讲。作为其中的一个重要要素的,可以说是基础的分词器,当然还是扮演了很关键的角色,查询的逻辑是以分词为基础的。分词是原石,而查询逻辑则能对它雕琢。

 

事实上如果没有用过StandardAnalyzer分词器,没有用它来解决一些问题,并且找到有哪些地方不足,那并不能弄清楚你要什么样的分词器。比如,现在有一些内容,用StandardAnalyzer作为分词器已经建立好了索引,接下来,进行查询操作。

 

 

代码 2.1.2.1

 

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

 

代码2.1.2.1,先是把四句话进行了索引,尔后,分别用5个词进行了查询。运行结果:

 

搜索词:中华
结果:
*
-----------------------------------
搜索词:中国
结果:
中国人民解放军
-----------------------------------
搜索词:人民
结果:
*
中国人民解放军
人民是伟大的,祖国是伟大的。
-----------------------------------
搜索词:中国人民
结果:
中国人民解放军
-----------------------------------
搜索词:人民
结果:
*
中国人民解放军
人民是伟大的,祖国是伟大的。
-----------------------------------

发现结果还很不错,结果都在我们的预料之中,StandardAnalyzer分词器很好啊!为什么说它不行呢?接着,用StandardAnalyzer分词器为网站建立了索引,然后开始使用,问题就出现了。用户输入的往往不是一个词,而是几个词,或者干脆就是一句话。把问题简化一下,就用代码2.1.2.1作为模型。假如,现在索引进了四句话变成这样:

(1)、英语单词,语法,口语都很重要。

(2)、口语,语法,单词都是英语的重要组成部分。

(3)、我们要学好英语不但要学语法,单词还有口语。

(4)、对于学英语,只掌握单词语法,还是没办法跟别人沟通,必须能说出流利的口语。

 

假设,我们要搜索这四句话,也用5中输入:
(1)、英语

(2)、语法

(3)、单词

(4)、口语

(5)、英语单词

 

测试,结果对于输入的1,2,3,4前四个关键词,没问题,而第5个只能搜索到一个结果,这就纳闷了,明明每句话都包含了“英语”,“单词”这两个词汇,为什么不行呢?而把输入词换成“英语口语”,更邪门!没了,一个结果都没有。这是为什么呢?这个要从Lucene.Net的查询表达式说起。

 

话说,为了让Lucene.Net能灵活得搜索,因此,Lucene.Net引入了查询表达式,就和T-Sql的查询语句差不多,只是表现的代码不一样。现在对代码2.1.2.1做一个调整,在Query query = parser.Parse(querystring);语句下面加一句“Console.WriteLine(query.ToString());”,这个输出的就是查询表达式。而对于“英语单词”这个词,代码2.1.2.1会把它解析为——content:"英 语 单 词"——意思是在content字段,找“英”,“语”,“单”,“词”这四个字,并且,这四个字要连在一起。这显然不是我们想要的。而在用baidu或者google搜索的时候,如果输入的多个词之间加上空格就不一样了,同样,放到这里来试试。把词变成“英语 单词”,测试一下。

测试结果:

 

搜索词:英语 单词
结果:
content:"英 语" content:"单 词"
英语单词,语法,口语都很重要。
口语,语法,单词都是英语的重要组成部分。
我们要学好英语不但要学语法,单词还有口语。
对于学英语,只掌握单词语法,还是没办法跟别人沟通,必须能说出流利的口语。
-----------------------------------

 

可以搜素到了,而表达式也变成了——content:"英 语" content:"单 词"。

现在将面临新的问题:怎么才能把“英语单词”变成“英语 单词”。你不能期望用户总会输入搜索关键词后,逐个加上空格区分。而事实上一个新问题又产生了。修正一个错误会产生另外两个错误,前人说的太正确了。在这个例子里可能看不出来,把例子换一下,把上面第四句话换成“好好学英语”。

 

测试结果:

-----------------------------------
搜索词:英语 单词
结果:
content:"英 语" content:"单 词"
英语单词,语法,口语都很重要。
口语,语法,单词都是英语的重要组成部分。
我们要学好英语不但要学语法,单词还有口语。
好好学英语。
-----------------------------------

 

“好好学英语”没有包含“单词”这个词,但是却被搜索到了。这是为什么?玩我了吧?嘿嘿,那是因为——content:"英 语" content:"单 词"——这个表达式是或者的关系,要是变成并且的关系,是不是能解决问题呢?尝试手动改造下表达式。把表达式变成“+content:\"英 语\" +content:\"单 词\"”,测试:

 

-----------------------------------
搜索词:+content:"英 语" +content:"单 词"
结果:
+content:"英 语" +content:"单 词"
英语单词,语法,口语都很重要。
口语,语法,单词都是英语的重要组成部分。
我们要学好英语不但要学语法,单词还有口语。
-----------------------------------

 

very good !这个才是我们想要的嘛!怎么自己构造表达式,这个还是留到第四章来系统的讲。既然“+content:\"英 语\" +content:\"单 词\"”,可以用,那是不是“+content:\"英\" +content:\"语\" +content:\"单\" +content:\"词\"”,也可以使用呢?嘿嘿自己试试看吧。