查看原文
其他

Elasticsearch 可用的中文分词器使用

zhisheng zhisheng 2021-09-05

中文分词器:

1、ik-analyzer

https://github.com/wks/ik-analyzer

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。

采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和最大词长两种切分模式;具有83万字/秒(1600KB/S)的高速处理能力。

采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符

优化的词典存储,更小的内存占用。支持用户词典扩展定义

针对Lucene全文检索优化的查询分析器IKQueryParser(作者吐血推荐);引入简单搜索表达式,采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。

Maven用法:

1<dependency>
2    <groupId>org.wltea.ik-analyzer</groupId>
3    <artifactId>ik-analyzer</artifactId>
4    <version>3.2.8</version>
5</dependency>

在IK Analyzer加入Maven Central Repository之前,你需要手动安装,安装到本地的repository,或者上传到自己的Maven repository服务器上。

要安装到本地Maven repository,使用如下命令,将自动编译,打包并安装:
mvn install -Dmaven.test.skip=true

Elasticsearch添加中文分词

安装IK分词插件

https://github.com/medcl/elasticsearch-analysis-ik

进入elasticsearch-analysis-ik-master

更多安装请参考博客:

1、为elastic添加中文分词 : http://blog.csdn.net/dingzfang/article/details/42776693

2、如何在Elasticsearch中安装中文分词器(IK+pinyin) :http://www.cnblogs.com/xing901022/p/5910139.html

3、Elasticsearch 中文分词器 IK 配置和使用 : http://blog.csdn.net/jam00/article/details/52983056

ik 带有两个分词器

ik_max_word :会将文本做最细粒度的拆分;尽可能多的拆分出词语

ik_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有

区别:

 1# ik_max_word
 2
 3curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_max_word' -d '联想是全球最大的笔记本厂商'
 4#返回
 5
 6{
 7  "tokens" : [
 8    {
 9      "token" : "联想",
10      "start_offset" : 0,
11      "end_offset" : 2,
12      "type" : "CN_WORD",
13      "position" : 0
14    },
15    {
16      "token" : "是",
17      "start_offset" : 2,
18      "end_offset" : 3,
19      "type" : "CN_CHAR",
20      "position" : 1
21    },
22    {
23      "token" : "全球",
24      "start_offset" : 3,
25      "end_offset" : 5,
26      "type" : "CN_WORD",
27      "position" : 2
28    },
29    {
30      "token" : "最大",
31      "start_offset" : 5,
32      "end_offset" : 7,
33      "type" : "CN_WORD",
34      "position" : 3
35    },
36    {
37      "token" : "的",
38      "start_offset" : 7,
39      "end_offset" : 8,
40      "type" : "CN_CHAR",
41      "position" : 4
42    },
43    {
44      "token" : "笔记本",
45      "start_offset" : 8,
46      "end_offset" : 11,
47      "type" : "CN_WORD",
48      "position" : 5
49    },
50    {
51      "token" : "笔记",
52      "start_offset" : 8,
53      "end_offset" : 10,
54      "type" : "CN_WORD",
55      "position" : 6
56    },
57    {
58      "token" : "本厂",
59      "start_offset" : 10,
60      "end_offset" : 12,
61      "type" : "CN_WORD",
62      "position" : 7
63    },
64    {
65      "token" : "厂商",
66      "start_offset" : 11,
67      "end_offset" : 13,
68      "type" : "CN_WORD",
69      "position" : 8
70    }
71  ]
72}
73
74
75# ik_smart
76
77curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_smart' -d '联想是全球最大的笔记本厂商'
78
79# 返回
80
81{
82  "tokens" : [
83    {
84      "token" : "联想",
85      "start_offset" : 0,
86      "end_offset" : 2,
87      "type" : "CN_WORD",
88      "position" : 0
89    },
90    {
91      "token" : "是",
92      "start_offset" : 2,
93      "end_offset" : 3,
94      "type" : "CN_CHAR",
95      "position" : 1
96    },
97    {
98      "token" : "全球",
99      "start_offset" : 3,
100      "end_offset" : 5,
101      "type" : "CN_WORD",
102      "position" : 2
103    },
104    {
105      "token" : "最大",
106      "start_offset" : 5,
107      "end_offset" : 7,
108      "type" : "CN_WORD",
109      "position" : 3
110    },
111    {
112      "token" : "的",
113      "start_offset" : 7,
114      "end_offset" : 8,
115      "type" : "CN_CHAR",
116      "position" : 4
117    },
118    {
119      "token" : "笔记本",
120      "start_offset" : 8,
121      "end_offset" : 11,
122      "type" : "CN_WORD",
123      "position" : 5
124    },
125    {
126      "token" : "厂商",
127      "start_offset" : 11,
128      "end_offset" : 13,
129      "type" : "CN_WORD",
130      "position" : 6
131    }
132  ]
133}

下面我们来创建一个索引,使用 ik
创建一个名叫 iktest 的索引,设置它的分析器用 ik ,分词器用 ik_max_word,并创建一个 article 的类型,里面有一个 subject 的字段,指定其使用 ik_max_word 分词器

1curl -XPUT 'http://localhost:9200/iktest?pretty' -d '{
2    "settings" : {
3        "analysis" : {
4            "analyzer" : {
5                "ik" : {
6                    "tokenizer" : "ik_max_word"
7                }
8            }
9        }
10    },
11    "mappings" : {
12        "article" : {
13            "dynamic" : true,
14            "properties" : {
15                "subject" : {
16                    "type" : "string",
17                    "analyzer" : "ik_max_word"
18                }
19            }
20        }
21    }
22}'

批量添加几条数据,这里我指定元数据 _id 方便查看,subject 内容为我随便找的几条新闻的标题

1curl -XPOST http://localhost:9200/iktest/article/_bulk?pretty -d '
2"index" : { "_id" : "1" } }
3{"subject" : ""闺蜜"崔顺实被韩检方传唤 韩总统府促彻查真相" }
4"index" : { "_id" : "2" } }
5{"subject" : "韩举行"护国训练" 青瓦台:决不许国家安全出问题" }
6"index" : { "_id" : "3" } }
7{"subject" : "媒体称FBI已经取得搜查令 检视希拉里电邮" }
8"index" : { "_id" : "4" } }
9{"subject" : "村上春树获安徒生奖 演讲中谈及欧洲排外问题" }
10"index" : { "_id" : "5" } }
11{"subject" : "希拉里团队炮轰FBI 参院民主党领袖批其“违法”" }
12'

查询 “希拉里和韩国”

1curl -XPOST http://localhost:9200/iktest/article/_search?pretty  -d'
2{
3    "query" : { "match" : { "subject" : "希拉里和韩国" }},
4    "highlight" : {
5        "pre_tags" : ["<font color='red'>"],
6        "post_tags" : ["</font>"],
7        "fields" : {
8            "subject" : {}
9        }
10    }
11}
12'
13#返回
14{
15  "took" : 113,
16  "timed_out" : false,
17  "_shards" : {
18    "total" : 5,
19    "successful" : 5,
20    "failed" : 0
21  },
22  "hits" : {
23    "total" : 4,
24    "max_score" : 0.034062363,
25    "hits" : [ {
26      "_index" : "iktest",
27      "_type" : "article",
28      "_id" : "2",
29      "_score" : 0.034062363,
30      "_source" : {
31        "subject" : "韩举行"护国训练" 青瓦台:决不许国家安全出问题"
32      },
33      "highlight" : {
34        "subject" : [ "<font color=red>韩</font>举行"护<font color=red>国</font>训练" 青瓦台:决不许国家安全出问题" ]
35      }
36    }, {
37      "_index" : "iktest",
38      "_type" : "article",
39      "_id" : "3",
40      "_score" : 0.0076681254,
41      "_source" : {
42        "subject" : "媒体称FBI已经取得搜查令 检视希拉里电邮"
43      },
44      "highlight" : {
45        "subject" : [ "媒体称FBI已经取得搜查令 检视<font color=red>希拉里</font>电邮" ]
46      }
47    }, {
48      "_index" : "iktest",
49      "_type" : "article",
50      "_id" : "5",
51      "_score" : 0.006709609,
52      "_source" : {
53        "subject" : "希拉里团队炮轰FBI 参院民主党领袖批其“违法”"
54      },
55      "highlight" : {
56        "subject" : [ "<font color=red>希拉里</font>团队炮轰FBI 参院民主党领袖批其“违法”" ]
57      }
58    }, {
59      "_index" : "iktest",
60      "_type" : "article",
61      "_id" : "1",
62      "_score" : 0.0021509775,
63      "_source" : {
64        "subject" : ""闺蜜"崔顺实被韩检方传唤 韩总统府促彻查真相"
65      },
66      "highlight" : {
67        "subject" : [ ""闺蜜"崔顺实被<font color=red>韩</font>检方传唤 <font color=red>韩</font>总统府促彻查真相" ]
68      }
69    } ]
70  }
71}

这里用了高亮属性 highlight,直接显示到 html 中,被匹配到的字或词将以红色突出显示。若要用过滤搜索,直接将 match 改为 term 即可

热词更新配置

网络词语日新月异,如何让新出的网络热词(或特定的词语)实时的更新到我们的搜索当中呢

先用 ik 测试一下

1curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_max_word' -d '
2成龙原名陈港生
3'

4#返回
5{
6  "tokens" : [ {
7    "token" : "成龙",
8    "start_offset" : 1,
9    "end_offset" : 3,
10    "type" : "CN_WORD",
11    "position" : 0
12  }, {
13    "token" : "原名",
14    "start_offset" : 3,
15    "end_offset" : 5,
16    "type" : "CN_WORD",
17    "position" : 1
18  }, {
19    "token" : "陈",
20    "start_offset" : 5,
21    "end_offset" : 6,
22    "type" : "CN_CHAR",
23    "position" : 2
24  }, {
25    "token" : "港",
26    "start_offset" : 6,
27    "end_offset" : 7,
28    "type" : "CN_WORD",
29    "position" : 3
30  }, {
31    "token" : "生",
32    "start_offset" : 7,
33    "end_offset" : 8,
34    "type" : "CN_CHAR",
35    "position" : 4
36  } ]
37}

ik 的主词典中没有”陈港生” 这个词,所以被拆分了。
现在我们来配置一下

修改 IK 的配置文件 :ES 目录/plugins/ik/config/ik/IKAnalyzer.cfg.xml

修改如下:

1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
3<properties>
4    <comment>IK Analyzer 扩展配置</comment>
5    <!--用户可以在这里配置自己的扩展字典 -->
6    <entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
7     <!--用户可以在这里配置自己的扩展停止词字典-->
8    <entry key="ext_stopwords">custom/ext_stopword.dic</entry>
9    <!--用户可以在这里配置远程扩展字典 -->
10    <entry key="remote_ext_dict">http://192.168.1.136/hotWords.php</entry>
11    <!--用户可以在这里配置远程扩展停止词字典-->
12    <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
13</properties>

这里我是用的是远程扩展字典,因为可以使用其他程序调用更新,且不用重启 ES,很方便;当然使用自定义的 mydict.dic 字典也是很方便的,一行一个词,自己加就可以了

既然是远程词典,那么就要是一个可访问的链接,可以是一个页面,也可以是一个txt的文档,但要保证输出的内容是 utf-8 的格式

hotWords.php 的内容

1$s = <<<'EOF'
2陈港生
3元楼
4蓝瘦
5EOF;

6header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'true200);
7header('ETag: "5816f349-19"');
8echo $s;

ik 接收两个返回的头部属性 Last-Modified 和 ETag,只要其中一个有变化,就会触发更新,ik 会每分钟获取一次
重启 Elasticsearch ,查看启动记录,看到了三个词已被加载进来

再次执行上面的请求,返回, 就可以看到 ik 分词器已经匹配到了 “陈港生” 这个词,同理一些关于我们公司的专有名字(例如:永辉、永辉超市、永辉云创、云创 …. )也可以自己手动添加到字典中去。

2、结巴中文分词

特点:

1、支持三种分词模式:

  • 精确模式,试图将句子最精确地切开,适合文本分析;

  • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;

  • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

2、支持繁体分词

3、支持自定义词典

3、THULAC

THULAC(THU Lexical Analyzer for Chinese)由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能。THULAC具有如下几个特点:

能力强。利用我们集成的目前世界上规模最大的人工分词和词性标注中文语料库(约含5800万字)训练而成,模型标注能力强大。

准确率高。该工具包在标准数据集Chinese Treebank(CTB5)上分词的F1值可达97.3%,词性标注的F1值可达到92.9%,与该数据集上最好方法效果相当。

速度较快。同时进行分词和词性标注速度为300KB/s,每秒可处理约15万字。只进行分词速度可达到1.3MB/s。

中文分词工具thulac4j发布

1、规范化分词词典,并去掉一些无用词;

2、重写DAT(双数组Trie树)的构造算法,生成的DAT size减少了8%左右,从而节省了内存;

3、优化分词算法,提高了分词速率。

1<dependency>
2  <groupId>io.github.yizhiru</groupId>
3  <artifactId>thulac4j</artifactId>
4  <version>${thulac4j.version}</version>
5</dependency>

http://www.cnblogs.com/en-heng/p/6526598.html

thulac4j支持两种分词模式:

SegOnly模式,只分词没有词性标注;

SegPos模式,分词兼有词性标注。

1// SegOnly mode
2String sentence = "滔滔的流水,向着波士顿湾无声逝去";
3SegOnly seg = new SegOnly("models/seg_only.bin");
4System.out.println(seg.segment(sentence));
5// [滔滔, 的, 流水, ,, 向着, 波士顿湾, 无声, 逝去]
6
7// SegPos mode
8SegPos pos = new SegPos("models/seg_pos.bin");
9System.out.println(pos.segment(sentence));
10//[滔滔/a, 的/u, 流水/n, ,/w, 向着/p, 波士顿湾/ns, 无声/v, 逝去/v]

4、NLPIR

中科院计算所 NLPIR:http://ictclas.nlpir.org/nlpir/ (可直接在线分析中文)

下载地址:https://github.com/NLPIR-team/NLPIR

中科院分词系统(NLPIR)JAVA简易教程: http://www.cnblogs.com/wukongjiuwo/p/4092480.html

5、ansj分词器

https://github.com/NLPchina/ansj_seg

这是一个基于n-Gram+CRF+HMM的中文分词的java实现.

分词速度达到每秒钟大约200万字左右(mac air下测试),准确率能达到96%以上

目前实现了.中文分词. 中文姓名识别 .

用户自定义词典,关键字提取,自动摘要,关键字标记等功能
可以应用到自然语言处理等方面,适用于对分词效果要求高的各种项目.

maven 引入:

1<dependency>
2            <groupId>org.ansj</groupId>
3            <artifactId>ansj_seg</artifactId>
4            <version>5.1.1</version>
5</dependency>

调用demo

1String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
2 System.out.println(ToAnalysis.parse(str));
3
4 欢迎/v,使用/v,ansj/en,_,seg/en,,,(,ansj/en,中文/nz,分词/n,),在/p,这里/r,如果/c,你/r,遇到/v,什么/r,问题/n,都/d,可以/v,联系/v,我/r,./m,我/r,一定/d,尽我所能/l,./m,帮助/v,大家/r,./m,ansj/en,_,seg/en,更快/d,,,更/d,准/a,,,更/d,自由/a,!

6、哈工大的LTP

https://link.zhihu.com/?target=https%3A//github.com/HIT-SCIR/ltp

LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic Link Library, DLL)的应用程序接口、可视化工具,并且能够以网络服务(Web Service)的形式进行使用。

关于LTP的使用,请参考: http://ltp.readthedocs.io/zh_CN/latest/

7、庖丁解牛

下载地址:http://pan.baidu.com/s/1eQ88SZS

使用分为如下几步:

  1. 配置dic文件:
    修改paoding-analysis.jar中的paoding-dic-home.properties文件,将“#paoding.dic.home=dic”的注释去掉,并配置成自己dic文件的本地存放路径。eg:/home/hadoop/work/paoding-analysis-2.0.4-beta/dic

  2. 把Jar包导入到项目中:
    将paoding-analysis.jar、commons-logging.jar、lucene-analyzers-2.2.0.jar和lucene-core-2.2.0.jar四个包导入到项目中,这时就可以在代码片段中使用庖丁解牛工具提供的中文分词技术,例如:

1Analyzer analyzer = new PaodingAnalyzer(); //定义一个解析器
2String text = "庖丁系统是个完全基于lucene的中文分词系统,它就是重新建了一个analyzer,叫做PaodingAnalyzer,这个analyer的核心任务就是生成一个可以切词TokenStream。"; <span style="font-family: Arial, Helvetica, sans-serif;">//待分词的内容</span>
3TokenStream tokenStream = analyzer.tokenStream(text, new StringReader(text)); //得到token序列的输出流
4try {
5    Token t;
6    while ((t = tokenStream.next()) != null)
7    {
8           System.out.println(t); //输出每个token
9    }
10catch (IOException e) {
11    e.printStackTrace();
12}

8、sogo在线分词

sogo在线分词采用了基于汉字标注的分词方法,主要使用了线性链链CRF(Linear-chain CRF)模型。词性标注模块主要基于结构化线性模型(Structured Linear Model)

在线使用地址为:
http://www.sogou.com/labs/webservice/

9、word分词

地址: https://github.com/ysc/word

word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过自定义配置文件来改变组件行为,能自定义用户词库、自动检测词库变化、支持大规模分布式环境,能灵活指定多种分词算法,能使用refine功能灵活控制分词结果,还能使用词频统计、词性标注、同义标注、反义标注、拼音标注等功能。提供了10种分词算法,还提供了10种文本相似度算法,同时还无缝和Lucene、Solr、ElasticSearch、Luke集成。注意:word1.3需要JDK1.8

maven 中引入依赖:

1<dependencies>
2    <dependency>
3        <groupId>org.apdplat</groupId>
4        <artifactId>word</artifactId>
5        <version>1.3</version>
6    </dependency>
7</dependencies>

ElasticSearch插件:

11、打开命令行并切换到elasticsearch的bin目录
2cd elasticsearch-2.1.1/bin
3
42、运行plugin脚本安装word分词插件:
5./plugin install http://apdplat.org/word/archive/v1.4.zip
6
7安装的时候注意:
8    如果提示:
9        ERRORfailed to download
10    或者
11        Failed to install word, reason: failed to download
12    或者
13        ERROR: incorrect hash (SHA1)
14    则重新再次运行命令,如果还是不行,多试两次
15
16如果是elasticsearch1.x系列版本,则使用如下命令:
17./plugin -u http://apdplat.org/word/archive/v1.3.1.zip -i word
18
193、修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
20index.analysis.analyzer.default.type : "word"
21index.analysis.tokenizer.default.type : "word"
22
234、启动ElasticSearch测试效果,在Chrome浏览器中访问:
24http://localhost:9200/_analyze?analyzer=word&text=杨尚川是APDPlat应用级产品开发平台的作者
25
265、自定义配置
27修改配置文件elasticsearch-2.1.1/plugins/word/word.local.conf
28
296、指定分词算法
30修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
31index.analysis.analyzer.default.segAlgorithm : "ReverseMinimumMatching"
32index.analysis.tokenizer.default.segAlgorithm : "ReverseMinimumMatching"
33
34这里segAlgorithm可指定的值有:
35正向最大匹配算法:MaximumMatching
36逆向最大匹配算法:ReverseMaximumMatching
37正向最小匹配算法:MinimumMatching
38逆向最小匹配算法:ReverseMinimumMatching
39双向最大匹配算法:BidirectionalMaximumMatching
40双向最小匹配算法:BidirectionalMinimumMatching
41双向最大最小匹配算法:BidirectionalMaximumMinimumMatching
42全切分算法:FullSegmentation
43最少词数算法:MinimalWordCount
44最大Ngram分值算法:MaxNgramScore
45如不指定,默认使用双向最大匹配算法:BidirectionalMaximumMatching

10、jcseg分词器

https://code.google.com/archive/p/jcseg/

11、stanford分词器

Stanford大学的一个开源分词工具,目前已支持汉语。

首先,去【1】下载Download Stanford Word Segmenter version 3.5.2,取得里面的 data 文件夹,放在maven project的 src/main/resources 里。

然后,maven依赖添加:

1<properties>
2        <java.version>1.8</java.version>
3        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4        <corenlp.version>3.6.0</corenlp.version>
5    </properties>
6    <dependencies>
7        <dependency>
8            <groupId>edu.stanford.nlp</groupId>
9            <artifactId>stanford-corenlp</artifactId>
10            <version>${corenlp.version}</version>
11        </dependency>
12        <dependency>
13            <groupId>edu.stanford.nlp</groupId>
14            <artifactId>stanford-corenlp</artifactId>
15            <version>${corenlp.version}</version>
16            <classifier>models</classifier>
17        </dependency>
18        <dependency>
19            <groupId>edu.stanford.nlp</groupId>
20            <artifactId>stanford-corenlp</artifactId>
21            <version>${corenlp.version}</version>
22            <classifier>models-chinese</classifier>
23        </dependency>
24    </dependencies>

测试:

1import java.util.Properties;
2
3import edu.stanford.nlp.ie.crf.CRFClassifier;
4
5public class CoreNLPSegment {
6
7    private static CoreNLPSegment instance;
8    private CRFClassifier         classifier;
9
10    private CoreNLPSegment(){
11        Properties props = new Properties();
12        props.setProperty("sighanCorporaDict""data");
13        props.setProperty("serDictionary""data/dict-chris6.ser.gz");
14        props.setProperty("inputEncoding""UTF-8");
15        props.setProperty("sighanPostProcessing""true");
16        classifier = new CRFClassifier(props);
17        classifier.loadClassifierNoExceptions("data/ctb.gz", props);
18        classifier.flags.setProperties(props);
19    }
20
21    public static CoreNLPSegment getInstance() {
22        if (instance == null) {
23            instance = new CoreNLPSegment();
24        }
25
26        return instance;
27    }
28
29    public String[] doSegment(String data) {
30        return (String[]) classifier.segmentString(data).toArray();
31    }
32
33    public static void main(String[] args) {
34
35        String sentence = "他和我在学校里常打桌球。";
36        String ret[] = CoreNLPSegment.getInstance().doSegment(sentence);
37        for (String str : ret) {
38            System.out.println(str);
39        }
40
41    }
42
43}

博客

https://blog.sectong.com/blog/corenlp_segment.html

http://blog.csdn.net/lightty/article/details/51766602

12、Smartcn

Smartcn为Apache2.0协议的开源中文分词系统,Java语言编写,修改的中科院计算所ICTCLAS分词系统。很早以前看到Lucene上多了一个中文分词的contribution,当时只是简单的扫了一下.class文件的文件名,通过文件名可以看得出又是一个改的ICTCLAS的分词系统。

http://lucene.apache.org/core/5_1_0/analyzers-smartcn/org/apache/lucene/analysis/cn/smart/SmartChineseAnalyzer.html

13、pinyin 分词器

pinyin分词器可以让用户输入拼音,就能查找到相关的关键词。比如在某个商城搜索中,输入 yonghui,就能匹配到 永辉。这样的体验还是非常好的。

pinyin分词器的安装与IK是一样的。下载地址:https://github.com/medcl/elasticsearch-analysis-pinyin

一些参数请参考 GitHub 的 readme 文档。

这个分词器在1.8版本中,提供了两种分词规则:

  • pinyin,就是普通的把汉字转换成拼音;

  • pinyin_first_letter,提取汉字的拼音首字母

使用:

1.Create a index with custom pinyin analyzer

1curl -XPUT http://localhost:9200/medcl/ -d'
2{
3    "index" : {
4        "analysis" : {
5            "analyzer" : {
6                "pinyin_analyzer" : {
7                    "tokenizer" : "my_pinyin"
8                    }
9            },
10            "tokenizer" : {
11                "my_pinyin" : {
12                    "type" : "pinyin",
13                    "keep_separate_first_letter" : false,
14                    "keep_full_pinyin" : true,
15                    "keep_original" : true,
16                    "limit_first_letter_length" : 16,
17                    "lowercase" : true,
18                    "remove_duplicated_term" : true
19                }
20            }
21        }
22    }
23}'

2.Test Analyzer, analyzing a chinese name, such as 刘德华

1http://localhost:9200/medcl/_analyze?text=%e5%88%98%e5%be%b7%e5%8d%8e&analyzer=pinyin_analyzer
1{
2  "tokens" : [
3    {
4      "token" : "liu",
5      "start_offset" : 0,
6      "end_offset" : 1,
7      "type" : "word",
8      "position" : 0
9    },
10    {
11      "token" : "de",
12      "start_offset" : 1,
13      "end_offset" : 2,
14      "type" : "word",
15      "position" : 1
16    },
17    {
18      "token" : "hua",
19      "start_offset" : 2,
20      "end_offset" : 3,
21      "type" : "word",
22      "position" : 2
23    },
24    {
25      "token" : "刘德华",
26      "start_offset" : 0,
27      "end_offset" : 3,
28      "type" : "word",
29      "position" : 3
30    },
31    {
32      "token" : "ldh",
33      "start_offset" : 0,
34      "end_offset" : 3,
35      "type" : "word",
36      "position" : 4
37    }
38  ]
39}

3.Create mapping

1curl -XPOST http://localhost:9200/medcl/folks/_mapping -d'
2{
3    "folks": {
4        "properties": {
5            "name": {
6                "type""keyword",
7                "fields": {
8                    "pinyin": {
9                        "type""text",
10                        "store""no",
11                        "term_vector""with_offsets",
12                        "analyzer""pinyin_analyzer",
13                        "boost"10
14                    }
15                }
16            }
17        }
18    }
19}'

4.Indexing

1curl -XPOST http://localhost:9200/medcl/folks/andy -d'{"name":"刘德华"}'

5.Let's search

1http://localhost:9200/medcl/folks/_search?q=name:%E5%88%98%E5%BE%B7%E5%8D%8E
2curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:%e5%88%98%e5%be%b7
3curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:liu
4curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:ldh
5curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:de+hua

6.Using Pinyin-TokenFilter

1curl -XPUT http://localhost:9200/medcl1/ -d'
2{
3    "index" : {
4        "analysis" : {
5            "analyzer" : {
6                "user_name_analyzer" : {
7                    "tokenizer" : "whitespace",
8                    "filter" : "pinyin_first_letter_and_full_pinyin_filter"
9                }
10            },
11            "filter" : {
12                "pinyin_first_letter_and_full_pinyin_filter" : {
13                    "type" : "pinyin",
14                    "keep_first_letter" : true,
15                    "keep_full_pinyin" : false,
16                    "keep_none_chinese" : true,
17                    "keep_original" : false,
18                    "limit_first_letter_length" : 16,
19                    "lowercase" : true,
20                    "trim_whitespace" : true,
21                    "keep_none_chinese_in_first_letter" : true
22                }
23            }
24        }
25    }
26}'

Token Test:刘德华 张学友 郭富城 黎明 四大天王

1curl -XGET http://localhost:9200/medcl1/_analyze?text=%e5%88%98%e5%be%b7%e5%8d%8e+%e5%bc%a0%e5%ad%a6%e5%8f%8b+%e9%83%ad%e5%af%8c%e5%9f%8e+%e9%bb%8e%e6%98%8e+%e5%9b%9b%e5%a4%a7%e5%a4%a9%e7%8e%8b&analyzer=user_name_analyzer
1{
2  "tokens" : [
3    {
4      "token" : "ldh",
5      "start_offset" : 0,
6      "end_offset" : 3,
7      "type" : "word",
8      "position" : 0
9    },
10    {
11      "token" : "zxy",
12      "start_offset" : 4,
13      "end_offset" : 7,
14      "type" : "word",
15      "position" : 1
16    },
17    {
18      "token" : "gfc",
19      "start_offset" : 8,
20      "end_offset" : 11,
21      "type" : "word",
22      "position" : 2
23    },
24    {
25      "token" : "lm",
26      "start_offset" : 12,
27      "end_offset" : 14,
28      "type" : "word",
29      "position" : 3
30    },
31    {
32      "token" : "sdtw",
33      "start_offset" : 15,
34      "end_offset" : 19,
35      "type" : "word",
36      "position" : 4
37    }
38  ]
39}

7.Used in phrase query

(1)、

1 PUT /medcl/
2  {
3      "index" : {
4          "analysis" : {
5              "analyzer" : {
6                  "pinyin_analyzer" : {
7                      "tokenizer" : "my_pinyin"
8                      }
9              },
10              "tokenizer" : {
11                  "my_pinyin" : {
12                      "type" : "pinyin",
13                      "keep_first_letter":false,
14                      "keep_separate_first_letter" : false,
15                      "keep_full_pinyin" : true,
16                      "keep_original" : false,
17                      "limit_first_letter_length" : 16,
18                      "lowercase" : true
19                  }
20              }
21          }
22      }
23  }
24  GET /medcl/folks/_search
25  {
26    "query": {"match_phrase": {
27      "name.pinyin""刘德华"
28    }}
29  }

(2)、

1PUT /medcl/
2  {
3      "index" : {
4          "analysis" : {
5              "analyzer" : {
6                  "pinyin_analyzer" : {
7                      "tokenizer" : "my_pinyin"
8                      }
9              },
10              "tokenizer" : {
11                  "my_pinyin" : {
12                      "type" : "pinyin",
13                      "keep_first_letter":false,
14                      "keep_separate_first_letter" : true,
15                      "keep_full_pinyin" : false,
16                      "keep_original" : false,
17                      "limit_first_letter_length" : 16,
18                      "lowercase" : true
19                  }
20              }
21          }
22      }
23  }
24
25  POST /medcl/folks/andy
26  {"name":"刘德华"}
27
28  GET /medcl/folks/_search
29  {
30    "query": {"match_phrase": {
31      "name.pinyin""刘德h"
32    }}
33  }
34
35  GET /medcl/folks/_search
36  {
37    "query": {"match_phrase": {
38      "name.pinyin""刘dh"
39    }}
40  }
41
42  GET /medcl/folks/_search
43  {
44    "query": {"match_phrase": {
45      "name.pinyin""dh"
46    }}
47  }


关注我

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存