Elasticsearch 使用 IK Analysis 实现中文分词
IK Analysis for Elasticsearch : medcl / elasticsearch-analysis-ik
Install
- 下载预编译包安装
在 ElasticSearch 根目录的 plugins 文件夹下创建 ik 文件夹。
bash
cd your-es-root/plugins/ && mkdir ik
解压下载的预编译包文件到 your-es-root/plugins/ik
- 使用 elasticsearch-plugin 安装
bash
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip
常见问题
- 分词测试失败 请在某个索引下调用 analyze 接口测试,而不是直接调用 analyze 接口 如:
bash
curl -XGET "http://localhost:9200/your_index/_analyze" -H 'Content-Type: application/json' -d'
{
"text":"中华人民共和国 MN","tokenizer": "my_ik"
}'
- ik_max_word 和 ik_smart 什么区别?
ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
SpringBoot & IK Analysis
实体定义
没有对应的索引时,会自动根据实体定义中的注解生成对应的索引。
注意:仅在应用启动时会根据注解的设置生成索引。如果应用运行的过程中删除了索引,之后再向索引中新增数据时,仅会根据默认设置生成索引。如 String 类型会默认定义为 keyword 类型,也不会使用指定的分词设置。
java
/**
* 名称
*/
@Field(store = true, index = true, type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
private String title;
上面代码生成的 field 属性如下:
json
{
"mappings": {
"elasticentitytype": {
"properties": {
"title": {
"analyzer": "ik_max_word",
"store": true,
"type": "text"
}
}
}
}
}
查询示例
java
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
if (StringUtils.isNotEmpty(parameter.getKey())) {
queryBuilder.should(QueryBuilders.matchQuery("title", parameter.getKey()));
}
Sort sort = Sort.by("createTime").descending();
Pageable pageable = PageRequest.of(parameter.getIndex() * parameter.getSize(), parameter.getSize(), sort);
Page<Blog> blogs = blogRepository.search(queryBuilder, pageable);
matchPhraseQuery 和 matchQuery 的区别
matchPhraseQuery
和 matchQuery
等的区别,在使用 matchQuery
等时,在执行查询时,搜索的词会被分词器分词,而使用 matchPhraseQuery
时,不会被分词器分词,而是直接以一个短语的形式查询,而如果你在创建索引所使用的 field 的 value 中没有这么一个短语(顺序无差,且连接在一起),那么将查询不出任何结果。