日常记录: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内容写法,不同版本写法还不一样。

相关推荐
放下华子我只抽RuiKe511 小时前
AI大模型开发-实战精讲:从零构建 RFM 会员价值模型(再进阶版:模拟数据 + 动态打分 + 策略落地)
大数据·人工智能·深度学习·elasticsearch·机器学习·搜索引擎·全文检索
@yanyu66614 小时前
第一个前后端分离项目
java·vue.js·springboot
惊讶的猫16 小时前
SpringMVC介绍
java·springmvc·springboot
Elastic 中国社区官方博客18 小时前
Elasticsearch Serverless 的无状态架构
大数据·数据库·elasticsearch·搜索引擎·云原生·架构·serverless
春日见18 小时前
自动驾驶流派
大数据·人工智能·深度学习·elasticsearch·搜索引擎
爱吃糖的z19 小时前
Elasticsearch Percolate Query使用优化案例-从2000到500ms
大数据·elasticsearch·搜索引擎
孫治AllenSun19 小时前
【Canal】监听mysql的binlog日志,同步数据到redis和es
redis·mysql·elasticsearch
大志学java20 小时前
idea中切换分支后,项目目录不显示的问题
java·elasticsearch·intellij-idea
堕落年代20 小时前
Meilisearch核心搜索逻辑与主流向量搜索引擎(Elasticsearch、Milvus)深度对比
elasticsearch·搜索引擎·milvus
掘根20 小时前
【即时通讯系统】环境搭建4——Elasticsearch(ES)
大数据·elasticsearch·搜索引擎