顾名思义,文本分析就是把全文本转换成一系列单词(term/token)的过程,也叫分词。在 ES 中,Analysis 是通过分词器(Analyzer) 来实现的,可使用 ES 内置的分析器或者按需定制化分析器。
举一个分词简单的例子:比如你输入 Mastering Elasticsearch,会自动帮你分成两个单词,一个是 mastering,另一个是 elasticsearch,可以看出单词也被转化成了小写的。
分词器的组成
执行分词过程的插件叫做分词器(Analyzer),分词器由下面三部分组成:
1. 字符过滤器(Character filter):
对文本中的特殊字符进行转换或过滤。例如通常我们要将文本中的HTML标签过滤掉,避免通过ul、li等标签也能搜索到目标文档。
2. 单词切分器(Tokenizer):
将一段全文本切分成多个单词(term)。对于英文,可以简单的使用空格作为分隔符对一个句子进行切分。但对于中文就复杂的多。
3. 单词过滤器(Token filter):
切分好的单词还要经过一系列Token filter的处理。
例如将所有英文单词转换为小写,无论我们输入的关键字是Python或是python,是Java或是JAVA都能正常支持搜索。
又例如过滤掉一些停用词(stopword),像英文中的“a”、“the”、“is”,中文中的“呢”、“的”、“是”,这些词对搜索几乎没有意义,所以也不会被放进倒排索引中。
再例如做一些近义词的替换或者增加一些相近的词,比如将“猜测”转换为“推测”、“才干”转换为“才能”。又比如给“蚂蚁金服”增加一个“支付宝”的近义词,这样使用两个关键词就都可以搜索到目标文档。
内置分词器
由于每种语言都有各自的特点,所以为了达到较好的分词效果,针对特定语言要使用特定的分词器。Elasticsearch中已经内置了很多分词器可以直接使用,也可以通过插件安装的方式增加额外的分词器,还可以通过组合特定的Character filter、Tokenizer和Token filter自定义你自己的分词器。下面我们对各类分词器进行详细的介绍。
standard Analyzer
可以看出是按照空格、非字母的方式对输入的文本进行了转换,比如对 QUICK 做了转小写,对一些停用词也没有去掉,比如 the。
Simple Analyzer
它只包括了 Lower Case 的 Tokenizer,它会按照非字母切分,非字母的会被去除,最后对切分好的做转小写处理。
Whitespace Analyzer
它非常简单,根据名称也可以看出是按照空格进行切分的,可以看出,只是按照空格进行切分,2 数字还是在的,QUICK 的首字母还是大写的,, 还是保留的。
Stop Analyzer
它由 Lowe Case 的 Tokenizer 和 Stop 的 Token Filters 组成的,相较于刚才提到的 Simple Analyzer,多了 stop 过滤,stop 就是会把 the,a,is 等修饰词去除。
Keyword Analyzer
它其实不做分词处理,只是将输入作为 Term 输出
Pattern Analyzer
它可以通过正则表达式的方式进行分词,默认是用 \W+ 进行分割的,也就是非字母的符合进行切分的,由于运行结果和 Stamdard Analyzer 一样,
Language Analyzer
ES 为不同国家语言的输入提供了 Language Analyzer 分词器,在里面可以指定不同的语言。
中文分词
中文分词有特定的难点,不像英文,单词有自然的空格作为分隔,在中文句子中,不能简单地切分成一个个的字,而是需要分成有含义的词,但是在不同的上下文,是有不同的理解的,例如下面这句话
乒乓球拍/卖/完了
乒乓球/拍卖/完了
目前,处理中文最常用的是IK分词器。但IK分词器并不是Elasticsearch的内置分词器,需要以插件的形式额外安装后才能使用。
IK分词器提供了两个分词算法:ik_smart和ik_max_word。其中ik_smart为最少词数量的切分,通常更贴近语义。
ik_smart
ik_max_word
可以看出 ik_max_word 比 ik_smart 划分的词条更多,这就是它们为什么叫做最细粒度和最粗粒度。