05、ElasticStack系列,第五章:IK分词器

devtools/2025/2/23 2:58:39/

ElasticStack系列,第五章:IK分词器

一、下载IK分词器插件

https://github.com/medcl/elasticsearch-analysis-ik/版本应该和你安装的Elasticsearch是对应的

二、安装IK分词器

##将其解压至 elasticsearch的plugins下即可

在这里插入图片描述

如果安装完IK分词器闪退可能是版本的问题

##修改下plugin-descriptor.properties文件
version=7.12.0
elasticsearch.version=7.12.0##然后重启ES

三、IK分词模式

1. 细粒度分词模式(ik_smart):
这是默认的分词模式,它会尽可能地将句子切分为最小的词语单元。它不仅可以识别普通词汇,还可以识别一些常见的专有名词、地名、人名等。2. 智能分词模式(ik_max_word):
这种模式会在细粒度分词的基础上,对长词进行进一步的切分。它可以识别更多的词语,但也会增加一些不必要的词语。这两种模式可以根据具体的需求选择使用。如果需要更细粒度的分词结果,可以选择细粒度分词模式;如果需要更全面的分词结果,可以选择智能分词模式。

测试:

http://192.168.73.107:9200/
post _analyze
{"analyzer": "ik_smart","text": "万般都是命,半点不由人"
}##结果:
{"tokens":[{"token":"万般都是命","start_offset":0,"end_offset":5,"type":"CN_WORD","position":0},{"token":"半点不由人","start_offset":6,"end_offset":11,"type":"CN_WORD","position":1}]
}
http://192.168.73.107:9200/
post _analyze
{"analyzer": "ik_max_word","text": "万般都是命,半点不由人"
}##结果:
{"tokens":[{"token":"万般都是命","start_offset":0,"end_offset":5,"type":"CN_WORD","position":0},{"token":"万般","start_offset":0,"end_offset":2,"type":"CN_WORD","position":1},{"token":"万","start_offset":0,"end_offset":1,"type":"TYPE_CNUM","position":2},{"token":"般","start_offset":1,"end_offset":2,"type":"CN_CHAR","position":3},{"token":"都是","start_offset":2,"end_offset":4,"type":"CN_WORD","position":4},{"token":"命","start_offset":4,"end_offset":5,"type":"CN_CHAR","position":5},{"token":"半点不由人","start_offset":6,"end_offset":11,"type":"CN_WORD","position":6},{"token":"半点","start_offset":6,"end_offset":8,"type":"CN_WORD","position":7},{"token":"不由","start_offset":8,"end_offset":10,"type":"CN_WORD","position":8},{"token":"由人","start_offset":9,"end_offset":11,"type":"CN_WORD","position":9}]
}

四、整合Springboot和Elasticsearch

1、版本依赖关系

在这里插入图片描述

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.15</version><relativePath />
</parent><!--springBoot2.5.15对应Elasticsearch7.12.0版本-->
<!--elasticsearch-->
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.12.0</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
spring:elasticsearch:rest:## 用于指定与Elasticsearch建立连接的服务器地址。 uris: http://192.168.73.107:9200## 用于指定与Elasticsearch建立连接的超时时间。 connection-timeout: 1s## 用于指定从Elasticsearch读取数据的超时时间。 read-timeout: 30s## 用于指定连接到Elasticsearch时使用的用户名和密码。username: elasticpassword: admin123sniffer:## 用于指定在连接失败后等待多长时间再次尝试连接。delay-after-failure: 1m## 用于指定多久进行一次节点发现。 interval: 5m

五、基于Java的Elasticsearch的增删改查

estTemplate_212">5.1、基于ElasticSearchRestTemplate的方式

5.1.1、创建实体
@Builder
@Data
@Document(indexName = "forum_index", createIndex = false, versionType = VersionType.EXTERNAL)
public class NovelES {@Idprivate String id;//分析类型 1小说 2章节 3文章@Field(store = true, type = FieldType.Integer)private Integer analyzeType;//主题编码@Field(store = false, type = FieldType.Keyword)private String themeCode;//主题名称@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String themeName;//小说编码@Field(store = false, type = FieldType.Keyword)private String novelCode;//小说名称@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String novelName;//小说作者+文章作者@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String author;//小说状态 1已完结 2连载中@Field(store = true, type = FieldType.Integer)private Integer novelStuts;//小说简介@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String synopsis;//章节编码@Field(store = false, type = FieldType.Keyword)private String chapterCode;//章节名称@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String chapterName;//文章编码@Field(store = false, type = FieldType.Keyword)private String articleCode;//文章简介@Field(store = true, analyzer = "ik_max_word", type = FieldType.Text)private String articleSynopsis;
}

解析:

@Document

在Elasticsearch中,@Document是一个注解,用于标记Java类,表示该类的对象将被映射到Elasticsearch索引中的文档。 @Document注解有以下属性,每个属性的内涵如下: 1. indexName: 确定文档所属的索引,可以通过索引名称进行检索和操作。 
2. type: 文档的类型,用于在索引中对文档进行分类。 
3. shards: 索引分片是将索引拆分为多个部分,以便在集群中进行分布式处理和存储。 
4. replicas: 索引副本是对索引中的分片进行复制,提供冗余和高可用性。 
5. createIndex: 指定是否在启动时自动创建索引,可以简化索引管理的过程。 
6. versionType: 文档版本控制的类型,用于处理并发更新和冲突解决。 
7. refreshInterval: 索引的刷新间隔决定了索引在内存中的更新频率。 
8. indexStoreType: 索引的存储类型定义了索引的物理存储方式,如使用文件系统还是内存。 

@Field

@Field注解用于在Java类中标记字段,并指定字段在Elasticsearch索引中的映射属性。以下是@Field注解的一些常用属性及其作用: 1. name:指定字段在索引中的名称。默认情况下,使用Java类中字段的名称。 
2. type:指定字段的数据类型。例如,text、keyword、date等。 
3. analyzer:指定用于分析文本字段的分析器。常用的分析器有standard、english、chinese等。 
4. index:指定字段是否被索引。可选值为true(默认)和false。如果设置为false,则该字段不会被搜索。 
5. store:指定是否将字段的原始值存储在索引中。可选值为true和false。如果设置为true,则可以从索引中检索到该字段的原始值。 
6. fielddata:指定是否为该字段启用fielddata。fielddata允许在聚合、排序和脚本中使用该字段的值。可选值为true和false。 
7. format:指定日期字段的格式。例如,"yyyy-MM-dd HH:mm:ss"。 
8. ignoreFields:指定在序列化和反序列化过程中要忽略的字段列表。 这些属性的值和作用如下: 1. name:可以自定义字段名称,用于在索引中标识该字段。 
2. type:指定字段的数据类型,决定了该字段的索引和搜索行为。 
3. analyzer:用于在索引和搜索过程中对文本进行分析和处理的分析器。 
4. index:确定字段是否应该被索引,即是否可以被搜索。 
5. store:确定是否将字段的原始值存储在索引中,以便可以检索到该值。 
6. fielddata:允许在聚合、排序和脚本中使用该字段的值。 
7. format:指定日期字段的格式,以便正确解析和处理日期值。 
8. ignoreFields:在序列化和反序列化过程中,可以忽略指定的字段,以便更精确地控制数据的序列化。

keyword与text

在Elasticsearch中, keyword 和 text 是两种常用的字段类型,它们在索引和搜索过程中有一些区别和影响。 1.  keyword 类型: -  keyword 类型是一种精确匹配的字段类型,通常用于存储结构化数据,如ID、标签、关键字等。 -  keyword 类型的字段会被索引为一个单独的项,不会被分词,可以被完全匹配搜索。 -  keyword 类型适用于需要进行精确匹配、聚合和排序的场景。 - 例子:一个商品的 category 字段,可能包含值如"电子产品"、"家具"、"服装"等,使用 keyword 类型可以方便地进行精确匹配和聚合操作。 2.  text 类型: -  text 类型是一种全文本字段类型,通常用于存储文本内容,如文章内容、商品描述等。 -  text 类型的字段会被分词,将文本拆分成单词或词项,以便进行全文搜索。 -  text 类型适用于需要进行全文搜索、模糊匹配和相关性排序的场景。 - 例子:一个文章的 content 字段,可以包含大段的文本内容,使用 text 类型可以进行全文搜索,找到包含关键词的文章。 影响和使用场景: 
-  keyword 类型适合于需要进行精确匹配、聚合和排序的场景,但不适合进行全文搜索。 
-  text 类型适合于需要进行全文搜索、模糊匹配和相关性排序的场景,但不适合进行精确匹配和排序。 需要根据具体的业务需求和查询场景选择合适的字段类型,可以根据字段的特性和使用方式来决定使用 keyword 还是 text 类型。
5.1.2、service
package espace">com.lee.forum.eskits.service;import espace">com.github.pagehelper.PageInfo;
import espace">com.lee.forum.eskits.model.NovelES;import espace">java.util.List;/*** @author Lee* @version 1.0* @description 小说ES操作集* @date 2023-11-22 15:33*/
public interface NovelESKitsService {/*** 查询小说信息--分页* @return*/PageInfo<NovelES> queryNovelEsInfo(Integer pageNumber,Integer pageSize,NovelES novelInfo);/*** 查询小说信息--不分页* @return*/List<NovelES> queryNovelEsInfo(NovelES novelInfo);/*** 批量更新 小说索引* @param novelESList* @return*/Boolean batchUpdateNovelEsInfo(List<NovelES> novelESList);/*** 批量删除 小说索引* @param novelESList* @return*/Boolean removeNovelEsInfo(List<NovelES> novelESList);}
package espace">com.lee.forum.eskits.service.impl;import espace">com.github.pagehelper.PageInfo;
import espace">com.lee.common.utils.StringUtils;
import espace">com.lee.forum.eskits.model.NovelES;
import espace">com.lee.forum.eskits.service.NovelESKitsService;
import espace">org.apache.commons.collections.CollectionUtils;
import espace">org.elasticsearch.index.query.BoolQueryBuilder;
import espace">org.elasticsearch.index.query.QueryBuilder;
import espace">org.elasticsearch.index.query.QueryBuilders;
import espace">org.springframework.data.domain.PageRequest;
import espace">org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import espace">org.springframework.data.elasticsearch.core.SearchHit;
import espace">org.springframework.data.elasticsearch.core.SearchHits;
import espace">org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import espace">org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import espace">org.springframework.stereotype.Service;import espace">javax.annotation.Resource;
import espace">java.util.List;
import espace">java.util.stream.Collectors;/*** @author Lee* @version 1.0* @description 小说ES操作集* @date 2023-11-22 15:33*/
@Service
public class NovelESKitsServiceImpl implements NovelESKitsService {@Resourceprivate ElasticsearchRestTemplate esRestTemplate;/*** 查询小说信息--分页** @return*/@Overridepublic PageInfo<NovelES> queryNovelEsInfo(Integer pageNumber, Integer pageSize, NovelES novelInfo) {QueryBuilder queryBuilder = getQueryBuilder(novelInfo);NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();builder.withQuery(queryBuilder);builder.withPageable(PageRequest.of(pageNumber, pageSize));NativeSearchQuery searchQuery = builder.build();SearchHits<NovelES> searchHits = esRestTemplate.search(searchQuery, NovelES.class);List<NovelES> novelESList = searchHits.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());PageInfo<NovelES> page = new PageInfo<>();page.setPageSize(pageSize);page.setPageNum(pageNumber);page.setTotal(searchHits.getTotalHits());page.setList(novelESList);return page;}/*** 查询小说信息--不分页** @return*/@Overridepublic List<NovelES> queryNovelEsInfo(NovelES novelInfo) {QueryBuilder queryBuilder = getQueryBuilder(novelInfo);NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();builder.withQuery(queryBuilder);NativeSearchQuery searchQuery = builder.build();SearchHits<NovelES> searchHits = esRestTemplate.search(searchQuery, NovelES.class);List<NovelES> novelESList = searchHits.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());return novelESList;}private QueryBuilder getQueryBuilder(NovelES novelInfo) {BoolQueryBuilder detlBoolQuery = new BoolQueryBuilder();if (novelInfo == null) {return detlBoolQuery;}//IDif (StringUtils.isNotEmpty(novelInfo.getId())) {detlBoolQuery.must(QueryBuilders.termQuery("id", novelInfo.getId()));}//分析类型 1小说 2章节 3文章if (novelInfo.getAnalyzeType() != null) {detlBoolQuery.must(QueryBuilders.termQuery("analyzeType", novelInfo.getAnalyzeType()));}//主题编码if (StringUtils.isNotEmpty(novelInfo.getThemeCode())) {detlBoolQuery.must(QueryBuilders.termQuery("themeCode", novelInfo.getThemeCode()));}//主题名称if (StringUtils.isNotEmpty(novelInfo.getThemeName())) {detlBoolQuery.must(QueryBuilders.wildcardQuery("themeName", "*" + novelInfo.getThemeName() + "*"));}//小说编码if (StringUtils.isNotEmpty(novelInfo.getNovelCode())) {detlBoolQuery.must(QueryBuilders.termQuery("novelCode", novelInfo.getNovelCode()));}//小说名称if (StringUtils.isNotEmpty(novelInfo.getNovelName())) {detlBoolQuery.must(QueryBuilders.wildcardQuery("novelName", "*" + novelInfo.getNovelName() + "*"));}//小说作者+文章作者if (StringUtils.isNotEmpty(novelInfo.getAuthor())) {detlBoolQuery.must(QueryBuilders.wildcardQuery("author", "*" + novelInfo.getAuthor() + "*"));}//小说状态 1已完结 2连载中if (novelInfo.getNovelStuts() != null) {detlBoolQuery.must(QueryBuilders.termQuery("novelStuts", novelInfo.getNovelStuts()));}//小说简介if (StringUtils.isNotEmpty(novelInfo.getSynopsis())) {detlBoolQuery.must(QueryBuilders.wildcardQuery("synopsis", "*" + novelInfo.getSynopsis() + "*"));}//章节编码if (StringUtils.isNotEmpty(novelInfo.getChapterCode())) {detlBoolQuery.must(QueryBuilders.termQuery("chapterCode", novelInfo.getChapterCode()));}//文章编码if (StringUtils.isNotEmpty(novelInfo.getArticleCode())) {detlBoolQuery.must(QueryBuilders.termQuery("articleCode", novelInfo.getArticleCode()));}//文章简介if (StringUtils.isNotEmpty(novelInfo.getArticleSynopsis())) {detlBoolQuery.must(QueryBuilders.wildcardQuery("articleSynopsis", "*" + novelInfo.getArticleSynopsis() + "*"));}return detlBoolQuery;}/*** 批量更新小说索引** @param novelESList* @return*/@Overridepublic Boolean batchUpdateNovelEsInfo(List<NovelES> novelESList) {if (CollectionUtils.isNotEmpty(novelESList)) {esRestTemplate.save(novelESList);}return true;}/*** 批量删除小说索引** @param novelESList* @return*/@Overridepublic Boolean removeNovelEsInfo(List<NovelES> novelESList) {if (CollectionUtils.isNotEmpty(novelESList)) {for (NovelES novelES : novelESList) {esRestTemplate.delete(novelES);}}return true;}
}

http://www.ppmy.cn/devtools/161085.html

相关文章

鸿蒙状态管理概述 v2

状态管理v2 概述状态管理之v2ObservedV2 和 Trace状态管理V1版本对嵌套类对象属性变化直接观测的局限性ObservedV2 和 Trace 使用场景 Local状态管理V1版本State装饰器的局限性 Param状态管理V1版本接受外部传入的装饰器的局限性 OnceEventComputedComputed 使用场景 TypePersi…

找不到依赖项 <…> (Maven)

IDEA 的 build 操作和 maven 的 build 操作是分开的 重新加载 Maven 项目

短视频平台“封号圈”乱象猖獗,IP查询技术助力整治

2月16日&#xff0c;澎湃新闻报道&#xff0c;小浩辛苦运营的账号&#xff0c;拥有5000多粉丝和400多条视频&#xff0c;却在一瞬间被陌生人恶意举报下架。更令人气愤的是&#xff0c;现在各大平台上竟然公然叫卖“封号圈”相关视频&#xff0c;提供“付费封号”“付费收徒”等…

2025年02月17日Github流行趋势

项目名称&#xff1a;OmniParser 项目地址url&#xff1a;https://github.com/microsoft/OmniParser 项目语言&#xff1a;Jupyter Notebook 历史star数&#xff1a;8971 今日star数&#xff1a;969 项目维护者&#xff1a;yadong-lu, ThomasDh-C, aliencaocao, nmstoker, kris…

IT服务运营管理体系的常用方法论与实践指南(上)

如何构建与业务深度协同的IT服务体系&#xff1f;如何通过技术管理实现成本与效能的双重升级&#xff1f;随着技术迭代加速、业务需求多变、系统复杂性攀升&#xff0c;这已成为企业管理者亟待解决的核心课题。 无论是传统企业的数字化转型&#xff0c;还是新兴科技企业的创新…

ue5 Arch vis AI traffic system 车辆系统添加不同种类的车

一、前置条件 资源包拥有二、步骤 添加第二辆车 在父级蓝图底下创建子级蓝图 打开子级蓝图 替换骨骼网格体 创建动画蓝图&#xff0c;骨骼选择该骨骼网格体的骨骼 连接动画蓝图 添加动画蓝图 添加资源包

Java版企电子招标采购系统源业码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

23种设计模式 - 模板方法

模式定义 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;它通过定义算法的骨架&#xff08;固定步骤&#xff09;&#xff0c;允许子类在不改变算法结构的情况下重写特定步骤。该模式的核心是将通用流程封装在基类中&#xff…