查了很多关于es 拼音分词器的文章,有价值的的不是很多,还是自己写一篇吧
分词分为读时分词和写时分词。
读时分词发生在用户查询时,ES 会即时地对用户输入的关键词进行分词,分词结果只存在内存中,当查询结束时,分词结果也会随即消失。而写时分词发生在文档写入时,ES 会对文档进行分词后,将结果存入倒排索引,该部分最终会以文件的形式存储于磁盘上,不会因查询结束或者 ES 重启而丢失。
写时分词器需要在 mapping 中指定,而且一经指定就不能再修改,若要修改必须新建索引。
分词一般在ES中有分词器处理。英文为Analyzer,它决定了分词的规则,Es默认自带了很多分词器,如:
Standard、english、Keyword、Whitespace等等。默认的分词器为Standard,通过它们各自的功能可组合
成你想要的分词规则。分词器具体详情可查看官网:分词器
另外,在常用的中文分词器、拼音分词器、繁简体转换插件。国内用的就多的分别是:
elasticsearch-analysis-ik
elasticsearch-analysis-pinyin
elasticsearch-analysis-stconvert
(插件需要下载自己es对应版本的插件,我得es版本是6.6.1,为了稳定没有采用7.x版本)
将下载的项目并用maven打包,在项目target文件夹下会生成elasticsearch-analysis-pinyin-6.6.1.zip
将压缩包 放到es plugins中,解压重命名analysis-pinyin ,重启es。
自定义setting
在resources目录下创建 elasticsearch_setting.json文件
{
"index": {
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"type": "pinyin",
//true:支持首字母
"keep_first_letter": true,
//false:首字母搜索只有两个首字母相同才能命中,全拼能命中
//true:任何情况全拼,首字母都能命中
"keep_separate_first_letter": false,
//true:支持全拼 eg: 刘德华 -> [liu,de,hua]
"keep_full_pinyin": true,
"keep_original": true,
//设置最大长度
"limit_first_letter_length": 16,
"lowercase": true,
//重复的项将被删除,eg: 德的 -> de
"remove_duplicated_term": true
}
}
}
}
}
在resources目录下创建 elasticsearch_mapping.json文件
{
"block": {
"properties": {
"preClosePx": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"blockTypeName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
} ,
"blockId": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"blockName": {
"type": "text",
"analyzer": "pinyin_analyzer",
"search_analyzer": "pinyin_analyzer",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
实体设置
@ToString
@Getter
@Setter
@Mapping(mappingPath = "elasticsearch_mapping.json")//设置mapping
@Setting(settingPath = "elasticsearch_setting.json")//设置setting
@Document(indexName = "info", type = "block", shards = 5, replicas = 1)
public class BlockInfoItem {
/**
* id
*/
@Id
private String id;
@Field(type = FieldType.Keyword)
private String preClosePx;
@Field(type = FieldType.Text)
private String blockTypeName;
@Field(type = FieldType.Text,analyzer = "pinyin_analyzer",searchAnalyzer = "pinyin_analyzer")
private String blockName;
@Field(type = FieldType.Keyword)
private String blockId;
}