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

相关推荐
执键行天涯2 小时前
【工具使用】VSCode如何将本地项目关联到远程的仓库 (vscode本地新项目与远程仓库建立链接)
ide·vscode·elasticsearch
lapiii3582 小时前
瑞吉外卖之com.fasterxml.jackson.dataformat.cbor.CBORFactor相关报错
java·springboot
再拼一次吧5 小时前
Elasticsearch
大数据·elasticsearch·搜索引擎
遇见你真好。5 小时前
SpringBoot整合quartz定时任务
java·springboot·quartz
VipSoft5 小时前
根据字符串,获取实体属性上的annotation,如:createTime” 找到对应实体属性中的 TableField(value = "create_time", fill = FieldFill.INSERT)
springboot
、十一、9 小时前
Linux中ES的安装
linux·运维·elasticsearch
苏少朋14 小时前
Es概念理解 ▎Es索引库操作 ▎Es文档操作
大数据·elasticsearch·搜索引擎
小小工匠14 小时前
ElasticSearch - Bucket Selector使用指南
elasticsearch·bucket sort
cab514 小时前
聊一聊Elasticsearch的一些基本信息
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客14 小时前
GraphQL 与 Elasticsearch 相遇:使用 Hasura DDN 构建可扩展、支持 AI 的应用程序
大数据·后端·elasticsearch·搜索引擎·全文检索·graphql·1024程序员节