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


    2.1.3 二元分词

     

    上一节通过变换查询表达式满足了需求,但是在实际应用中,如果那样查询,会出现另外一个问题,因为,那样搜索,是只要出现这个字,不管它出现在什么位置。这就产生了上一小节开头讲的,对准确性产生了极大干扰。比如,如果有一段这样的话:“这是一个雄!他有无法用汇形容的孤,但是他并没有用言来表达。”这句话包含了“英 语 单 词”这四个字,但是却和“英语单词”一点关系都没有。首先想到的解决方法,就是把句子按词来划分,那么就能有效的降低干扰。最简单的解决方法,莫过于每两个字组成一个部分。

    下面来构造核心算法。首先我们期望,只有中文(广义上指双字节文字,比如日文,韩文也在这个范围。)是按照二元拆分,而符号则是单符号拆分,对于英文则保持原样。因此,需要一个判断当前字符类型的函数。首先,构造一个枚举,如代码2.1.3.1。

    代码 2.1.3.1

    Code

    接下来需要有一个函数能够识别字符,把字符类型转换成我们需要的CharType。

    代码 2.1.3.2

    Code

    代码2.1.3.2粗略完成了我们想要的功能。现在就可以构造我们想要的算法了。

    代码 2.1.3.3

    Code

    代码2.1.3.3就是构造完后的算法。意思就是把英文字母,数字按空格或者符号划分,而中文则二元拆分。现在来测试下效果。

    代码 2.1.3.4

    Code

    代码 2.1.3.4 就是测试代码,测试的输入包含了各种字符。来看一下效果。

    测试结果:

    我是 0 2
    一个 2 4
    中国 4 6
    人 6 7
    , 7 8
    代码 8 10
    yurow 10 15
    001 15 18
    , 18 19
    真是 19 21
    个好 21 23
    名字 23 25
    啊 25 26
    ! 26 27
    ! 27 28
    ! 28 29
    哈哈 29 31
    哈 31 32
    。 32 33
    。 33 34
    。 34 35

    应该说结果符合我们的预期。下来写个Analyzer包装,并把这个包装应用到上一节2.1.2 的方案里去。

    代码 2.1.3.5

    Code

    代码2.1.3.5就是包装的结果。测试结果:

    搜索词:英语
    结果:
    content:英语
    -----------------------------------
    搜索词:语法
    结果:
    content:语法
    -----------------------------------
    搜索词:单词
    结果:
    content:单词
    -----------------------------------
    搜索词:口语
    结果:
    content:口语
    -----------------------------------
    搜索词:+content:"英" +content:"语" +content:"单" +content:"词"
    结果:
    +content:英 +content:语 +content:单 +content:词
    -----------------------------------

    What's happened? 为什么没有结果?分词器写错了?不要灰心!让我们来分析一下。在DoubleTokenizer类构造函数下一个断点,调试。因为,如果能正确运行,这个构造函数肯定要进入的。调试后看到了什么?传入的TextReader的类型是Lucene.Net.Index.DocumentsWriter.ReusableStringReader。查看Lucene.Net.Index.DocumentsWriter.ReusableStringReader类的定义,它继承自StringReader类,但是它重写掉了一些方法,而且,我们并没有发现我们使用的ReadToEnd方法。问题可能出在这里。看到ReusableStringReader类重写的Read(char[],int,int)方法,试试这个。

    代码 2.1.3.6

    Code

    代码改造成了2.1.3.6。主要的改变在于用父类的input字段保持了读入流,然后用Token作为缓冲区,因为它实现了可变缓冲区,简化了我们的开发。测试结果。

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

    终于OK了!!!呵呵。

    (PS:长时间编写,可能内容太长了,造成我机器编写这个章节有点卡,所以,这里提前结束。)


     

  • 相关阅读:
    H5实现的时钟
    Hystrix 熔断机制原理
    Redis模块化基本介绍
    Redis Pipeline原理分析
    Redis事务原理分析
    Java NIO原理分析
    Java Reference 源码分析
    JDK AtomicInteger 源码分析
    Java 包装类笔记
    Spring Cache 笔记
  • 原文地址:https://www.cnblogs.com/birdshover/p/1279894.html
Copyright © 2020-2023  润新知