日常记录:es 简单的自义定分词规则

背景

需求是存储时候分词词组是固定的,有关键词这一数据用|竖线连接,对于搜索时候只能匹配这些分割后的关键词词组。这就需要用到内置分词器Patter Analyzer,匹配规则是单竖线。找了好多文章零零散散,还是自己写个简单例子吧。

一、给字段定义分词规则

在springboot的resources下面建es文件夹,同时创建mapping.json、settings.json文件,文件名可以根据自己实际命名。

settings.json,使用pattern的正则匹配,用竖线作为分词规则。vertical_line是自定义分词器名字,后面直接引用这个名字。

{

"analysis": {

"analyzer": {

"vertical_line": {

"type": "pattern",

"pattern": "\\|"

}

}

}

}

mapping.json,question_info是@Document type值,properties里面是对应字段,这里对字段keyWords设置analyzer为vertical_line,就是存储时候分词使用竖线,然后search_analyzer查询分词器使用ik的ik_max_word最大限度分词。

{

"question_info": {

"properties": {

"keyWords": {

"type": "text",

"analyzer": "vertical_line",

"search_analyzer": "ik_max_word"

}

}

}

}

model,@Setting引用settings.json文件,@Mapping引用mapping.json文件,@Document 定义index名称以及mapping名称

package com.xxxx.model;

import java.util.*;

import org.springframework.data.annotation.Id;

import org.springframework.data.elasticsearch.annotations.Document;

import org.springframework.data.elasticsearch.annotations.Mapping;

import org.springframework.data.elasticsearch.annotations.Setting;

import lombok.Builder;

import lombok.Data;

import lombok.NoArgsConstructor;

import lombok.AllArgsConstructor;

/**

* 描述:xxx实体类

* @author sakyoka

* @date 2024-09-25 17:22:56

*/

@Data

@Builder

@NoArgsConstructor

@AllArgsConstructor

@Document(indexName = "question_info", type = "question_info")

//自定义分割,产品要求关键词查询,关键词由|竖线符号连接

@Setting(settingPath = "es/settings.json")

@Mapping(mappingPath = "es/mapping.json")

public class QuestionInfoModel {

/** 主键*/

@Id

private String id;

/** 关键词*/

private String keyWords;

}

二、初始化 index

好了,给实体类配置好之后还需要初始化index逻辑,这里我的想法是项目启动初始化一遍。

package com.xxxx.listener;

import java.util.ArrayList;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.boot.CommandLineRunner;

import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;

import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**

*

* 描述:启动完之后初始化配置

* @author sakyoka

* @date 2022年1月15日 下午9:36:12

*/

@Component

@Slf4j

public class SpringStartCompleteInitConfigListener implements CommandLineRunner{

@Resource

private ElasticsearchRestTemplate elasticsearchRestTemplate;

@Override

public void run(String... args) throws Exception {

try {

log.info("检测es index,进行初始化...");

List<Class<?>> clss = new ArrayList<>(1);

clss.add(QuestionInfo.class);

clss.stream().filter(cls -> {

//已经存在的跳过

return !elasticsearchRestTemplate.indexExists(cls);

}).forEach(cls -> {

//创建index

elasticsearchRestTemplate.createIndex(cls);

//添加mapping

elasticsearchRestTemplate.putMapping(cls);

});

log.info("检测es index完毕。");

} catch (Exception e) {

log.error("初始化es index失败", e);

}

}

}

这里初始化值得注意的是 elasticsearchRestTemplate.createIndex(cls)仅仅是创建了index和setting数据。如果要给字段引用对应分词器规则还需要putMapping 、elasticsearchRestTemplate.putMapping(cls);

好了,启动项目之后,测试一下效果。

postman测试es请求,由于之前开启了登录,postman需要设置一下认证信息,在authorization选在Basic auth填写对应账号密码

1、首先查询下,建立index逻辑看是否正确,可以看到index里面包含了自定义分词规则,以及对应字段引用了自定义分词器。

2、测试分词规则,可以看到分词器按照竖线分词

3、真实数据测试,这里就不测试了。。

三、词库追加自定义词组(补)

经测试,存储分词达到自己用竖线分词,但是用ik的ik_max_word去分词,发现没有达到自己的效果,用ik_max_word去分词发现少了一些词组,最后发现是词库没有这词组。那现在就需要给ik的词库添加自己想要的词组。

进入到es目录,进入到plugins,找到ik(需要自己去上传解压到这个目录),进入config目录,添加自定义词库文件,这里简单定义创建my.dic,往里面塞词组,这里添加港澳通行证,因为经测试这个词组出不来(6.8.12版本)

然后修改IKAnalyzer.cfg.xml,在ext_dict添加自己的自定义文件,添加好后重启es

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>

<comment>IK Analyzer 扩展配置</comment>

<!--用户可以在这里配置自己的扩展字典 -->

<entry key="ext_dict">my.dic</entry>

<!--用户可以在这里配置自己的扩展停止词字典-->

<entry key="ext_stopwords"></entry>

<!--用户可以在这里配置远程扩展字典 -->

<!-- <entry key="remote_ext_dict">words_location</entry> -->

<!--用户可以在这里配置远程扩展停止词字典-->

<!-- <entry key="remote_ext_stopwords">words_location</entry> -->

</properties>

最后发现能对这个分词了

总结

1、有个巨坑不知道为啥用注解@Field指定自定义分词器失败,然后这里才需要用mapping设置字段分词器,有朋友知道吗

2、mapping内容写法,不同版本写法还不一样。

相关推荐
feilieren34 分钟前
Docker 安装 Elasticsearch 9
运维·elasticsearch·docker·es
Java烘焙师4 小时前
架构师必备:业务扩展模式选型
mysql·elasticsearch·架构·hbase·多维度查询
G皮T17 小时前
【Elasticsearch】深度分页及其替代方案
大数据·elasticsearch·搜索引擎·scroll·检索·深度分页·search_after
G皮T20 小时前
【Elasticsearch】检索排序 & 分页
大数据·elasticsearch·搜索引擎·排序·分页·检索·深度分页
飞询1 天前
Docker 安装 Elasticsearch 9
elasticsearch·docker
G皮T1 天前
【Elasticsearch】检索高亮
大数据·elasticsearch·搜索引擎·全文检索·kibana·检索·高亮
保持学习ing1 天前
苍穹外卖day3--公共字段填充+新增菜品
java·阿里云·实战·springboot·前后端·外卖项目·阿里云文件存储
大只鹅2 天前
解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
spring boot·后端·elasticsearch
HGW6892 天前
基于 Elasticsearch 实现地图点聚合
java·elasticsearch·高德地图
默默coding的程序猿2 天前
3.前端和后端参数不一致,后端接不到数据的解决方案
java·前端·spring·ssm·springboot·idea·springcloud