Elasticsearch入门及常用命令和Spring中的常用操作

入门

官网

简介

  • 一个分布式的、Restful风格的搜索引擎。
  • 支持对各种类型的数据的检索。
  • 搜索速度快,可以提供实时的搜索服务。
  • 便于水平扩展,每秒可以处理PB级海量数据。

常用术语

  • 索引:与MySQL数据库中的Database相对应
  • 类型:与MySQL数据库中的Table相对应
  • 文档: 相当于MySQL中的一条数据,采用JSON结构
  • 字段:对应MySQL数据库中的一列

在ES6.0之后,前两个术语与MySQL对应逐步发生变化,删除了类型,变成一个索引对应一张表,但是保留了类型这个单词。

在ES7.0之后,逐步删除类型。

  • 集群:多台服务器组合在一起,分布式部署,提高整体性能
  • 节点:集群中的每台服务器,称呼为节点
  • 分片:一个索引相当于一张表,分片则是对这个索引进行划分,提高并发能力。
  • 副本:对分片进行备份,一个分片可以有多个备份,提高系统可用性。

安装与配置

对于Elasticsearch的下载,最好在对应项目中,找到父级依赖所确定的版本,因为这是经过测试,与当前Spring Boot版本最匹配的版本。

往期版本下载地址

下载完成后,解压到不含有中文的目录,目录结果如下图所示:

image

版本不一致,目录结构可能会有所区别。

配置

配置文件

配置主要是配置config目录下的elasticsearch.yml文件;配置内容如下所示:

# 集群名字
cluster.name: my-application
# 数据存储位置
path.data: E:\Data\elasticsearch\es-7.15.2\data
# 运行时产生日志 存储位置
path.logs: E:\Data\elasticsearch\es-7.15.2\logs

配置结果如下图所示:

在这里插入图片描述

配置环境变量

进入配置环境变量界面步骤:系统->系统信息->高级系统设置->环境变量

在系统变量的Path中新建环境变量;如下图所示:

image

安装中文分词插件

ES默认进行英文分词,需要安装中文分词插件来对中文进行分词,即可对中文关键词进行检索。

对应Elasticsearch版本来下载对应的中文分词插件。

下载地址

首先在Elasticsearch安装目录下的,plugins目录下,新建一个ik文件夹,然后将分词插件解压到ik目录下,如下图所示:

image

在config目录下,有许多dic字典文件,里面包含很多中文词语,除此之外,若需要新增当前流行的"网络词语",需要在IKAnalyzer.cfg.xml文件中进行配置。

安装ApiPost

该工具在操作和界面上与postman类似,但是功能比postman更多,主要用来进行API设计、调试、测试等;且支持中文。

  • ApiPost官网
  • Postman官网

因为ES服务器,通过命令行存储某些数据;过长不方便,可以用ApiPost模拟网页,发送HTTP请求,往ES服务器中添加数据更为方便。

除此之外,当需要查询某些复杂数据时,也可以用ApiPost来简化数据查询。

运行Elasticsearch

可以通过双击bin目录下的elasticsearch.bat文件直接启动,也可以在命令行启动。

若出现如下报错:

[DESKTOP-CO3SKTG] error updating geoip database [GeoLite2-ASN.mmdb]

则在配置文件中添加如下配置,再重新启动即可。

ingest.geoip.downloader.enabled: false

即禁止geoip数据库的更新。

启动后结果如下:

在这里插入图片描述

常见命令操作

因为配置过环境变量,所以可以直接在任意位置的命令行中,执行ES命令。

查询ES健康状况

curl -X GET "localhost:9200/_cat/health?v"

ES默认端口为9200v表示显示标题,使用GET请求获取数据;执行结果如下所示:

在这里插入图片描述

第一行是标题,第二行是显示的数据。

  1. timestamp:表示事件
  2. cluster:集群名
  3. status:状态;green表示很健康
  4. node.total:集群的节点个数
  5. node.data:集群数据节点个数

查询节点

执行如下命令,查看集群节点;

curl -X GET "localhost:9200/_cat/nodes?v"

结果如下:

在这里插入图片描述

查看索引

执行如下命令;

curl -X GET "localhost:9200/_cat/indices?v"

结果如下:
在这里插入图片描述

结果显示当前并未有索引。

新建索引

新建索引采用的是PUT请求,执行命令如下:

curl -X PUT "localhost:9200/test"

表示新建test索引;执行结果如下图:
image

返回结果为JSON格式。

此时再次查询索引,则会显示出一条索引,且因为没有给索引进行分片和备份,所以健康状况会显示yellow,结果如下图:

image

删除索引

删除索引,使用DELETE请求,执行命令如下所示:

curl -X DELETE "localhost:9200/test"

删除名为test的索引;执行结果如下图所示:

image

此时再次查询索引则不存在名为test的索引,如下图所示:

在这里插入图片描述

使用ApiPost访问ES

查询索引

如图所示:
image

新建索引

如图所示:

image

再次查询索引即可查到名为test的索引,如下图所示:

在这里插入图片描述

删除索引

如图所示:

在这里插入图片描述

插入数据

如下图所示:

在这里插入图片描述

使用PUT请求,插入数据,会自动创建索引test_doc插入数据类型,表示占位,1则是插入数据的id;插入数据格式为JSON

查询数据

如下图所示:
image

查询使用GET请求,表示查询索引为test,占位为_docid为1的数据。

修改数据

如下图所示:

在这里插入图片描述

修改数据其实与插入数据一致,在同样的位置修改数据,在底层就是先删除该位置原先存在的数据,并插入新的数据。

删除数据

如下图所示:

image

删除数据使用的是DELETE请求,返回结果确认删除;此时再次查询,则数据不存在,如下图所示:

image

查询索引对应所有数据

如图所示:

在这里插入图片描述

test表示索引名。

根据索引的单字段条件查询

如图所示:

在这里插入图片描述

q表示查询的条件,title:互联网则表示含有title字段,且字段内容含有互联网的数据。

且ES在查询时,会先将条件分割为多个词条,然后去查询包含对应字条的数据。

根据索引的多字段条件查询

如图所示:

在这里插入图片描述

多字段查询格式如图所示;query表示条件,multi_match表示多个匹配,fields则表示匹配条件的字段。

Spring整合Elasticsearch

引入依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-elasticsearch -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置Elasticsearch

在配置文件application.properties中配置如下内容:

# 连接集群节点
spring.elasticsearch.uris=localhost:9200

出现Redis与Elasticsearch发生Netty冲突

主要是Redis与Elasticsearch都调用了NettyRuntime类的setAvailableProcessors方法。

解决办法

在Application启动类中,添加如下内容:

@PostConstruct	// 所注解的方法 会在构造器调用完以后调用public void init() {// 解决Netty启动冲突问题// 由Netty4Utils.setAvailableProcessors()得System.setProperty("es.set.netty.runtime.available.processors", "false");}

配置实体

即配置项目实体与ElasticSearch相对应;即可自动生成与某实体相对应的索引;具体实体类配置如下所示:

/*** @author 花木凋零成兰* @date 2024/3/4 20:16*/
@Document(indexName = "discusspost")    // 与Elasticsearch关联 设置索引 注意不能出现大写字母
public class DiscussPost {@Id // 与ES索引对应字段private int id;@Field(type = FieldType.Integer)    // type字段类型private int userId;/*** analyzer时候的解析器   ik_max_word 尽可能的拆分* searchAnalyzer搜索时候的解析器   ik_smart 灵活的拆分*/@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")private String title;@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")private String content;@Field(type = FieldType.Integer)private int type;@Field(type = FieldType.Integer)private int status;@Field(type = FieldType.Date)private Date createTime;@Field(type = FieldType.Integer)private int commentCount;@Field(type = FieldType.Double)private double score;}

配置接口

配置完实体类后,还需要配置对ES操作接口,即接口内自动包含了与ES有关的API;接口配置如下所示:

/*** ES操作接口* @author 花木凋零成兰* @date 2024/3/25 21:14*/
@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
}

自定义接口继承ElasticsearchRepository<K, V>类,自定义接口内即有关于ES操作的API,K指操作的数据实体类型,V指数据实体类型的id类型。

测试

在ES7中,ElasticsearchRepository主要用来实现简单的对数据增删改查,即主要用于实现简单操作;ElasticsearchRestTemplate类则主要用来实现对数据的复杂查询等;即主要用户复杂的数据操作。

测试代码如下:

/*** @author 花木凋零成兰* @date 2024/3/25 21:15*/
@SpringBootTest
@ContextConfiguration(classes = Application.class)		// 使用Application类的配置
public class ElasticsearchTests {@Autowiredprivate DiscussPostMapper discussPostMapper;@Autowired()private DiscussPostRepository discussPostRepository;@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate; // 多用于复杂查询@Testpublic void insertTest() {// 测试插入数据 若不存在索引 会自动创建discussPostRepository.save(discussPostMapper.selectDiscussPostById(241));   // 每次插入一条数据discussPostRepository.save(discussPostMapper.selectDiscussPostById(242));discussPostRepository.save(discussPostMapper.selectDiscussPostById(243));}@Testpublic void insertListTest() {discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(101, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(102, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(103, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(111, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(112, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(131, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(132, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(133, 0, 100));   // 一次性插入多条数据discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(134, 0, 100));   // 一次性插入多条数据}@Testpublic void updateTest() {DiscussPost discussPost = discussPostMapper.selectDiscussPostById(231);discussPost.setContent("我是Java程序员,我要好好学Java!");discussPostRepository.save(discussPost);    // 在同样id处重新插入数据 覆盖原先数据}@Testpublic void deleteTest() {discussPostRepository.deleteById(231);  // 根据id删除数据}@Testpublic void deleteAllTest() {discussPostRepository.deleteAll();  // 一次性删除所有数据}@Testpublic void testSearch() {// 构造搜索条件NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))    // 构建搜索条件 多字段查询内容.withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC), // 构建排序顺序 先按照type倒序排SortBuilders.fieldSort("score").order(SortOrder.DESC), // 再按score倒序排SortBuilders.fieldSort("createTime").order(SortOrder.DESC)  // 再按创建时间 倒序排).withPageable(PageRequest.of(0, 10))    // 分页查询 第几页, 该页显示数据数量.withHighlightFields(   // 配置字段高亮显示new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")).build();SearchHits<DiscussPost> searchHits = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);if (searchHits.getTotalHits() <= 0) {      // 若查询无数据new PageImpl<DiscussPost>(null, PageRequest.of(0, 20), 0);}List<DiscussPost> discussPostList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());    // 将查询的数据转化为List集合Page<DiscussPost> page = new PageImpl<>(discussPostList, searchQuery.getPageable(), searchHits.getTotalHits());System.out.println(page.getTotalElements());  // 获取总数System.out.println(page.getNumber());    // 获取页码System.out.println(page.getSize());  // 获取每页个数System.out.println(page.getTotalPages());    // 分页总数for (DiscussPost discussPost : page) {System.out.println(discussPost);    // 输出查询结果}}@Testpublic void testSearchByTemplateHighLight() {   // 按条件查询数据 实现高亮NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))    // 构建搜索条件 多字段查询内容.withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC), // 构建排序顺序 先按照type倒序排SortBuilders.fieldSort("score").order(SortOrder.DESC), // 再按score倒序排SortBuilders.fieldSort("createTime").order(SortOrder.DESC)  // 再按创建时间 倒序排).withPageable(PageRequest.of(0, 10))    // 分页查询 第几页, 该页显示数据数量.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>"))   // 配置字段高亮显示.build();SearchHits<DiscussPost> searchHits = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);// SearchPage<DiscussPost> page = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());// 获取高亮结果集List<DiscussPost> list = new ArrayList<>();for (SearchHit<DiscussPost> searchHit : searchHits) {DiscussPost discussPost = searchHit.getContent();if (searchHit.getHighlightFields().get("title") != null) {discussPost.setTitle(searchHit.getHighlightFields().get("title").get(0));// discussPost.setContent(searchHit.getHighlightField("content").toString());}if (searchHit.getHighlightFields().get("content") != null) {discussPost.setContent(searchHit.getHighlightFields().get("content").get(0));// discussPost.setContent(searchHit.getHighlightField("content").toString());}list.add(discussPost);}// 组装分页对象Page<DiscussPost> pageInfo = new PageImpl<>(list, searchQuery.getPageable(), searchHits.getTotalHits());System.out.println(pageInfo.getTotalElements());    // 获取查询得到数据总数System.out.println(pageInfo.getTotalPages());   // 获取总页数System.out.println(pageInfo.getNumber());   // 获取当前页码System.out.println(pageInfo.getSize());     // 获取当前页面个数// 输出分页结果for (DiscussPost discussPost : pageInfo) {System.out.println(discussPost);}}
}

因测试数据过多,此处只展示最后一个测试方法执行成功结果;如下所示:

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/287530.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网络】IP 协议

网络层IP协议 一、认识 IP 地址二、IP 协议报头格式三、网段划分1. 初识子网划分2. 理解子网划分3. 子网掩码4. 特殊的 IP 地址5. IP 地址的数量限制6. 私有 IP 地址和公网 IP 地址7. 理解全球网络&#xff08;1&#xff09;理解公网&#xff08;2&#xff09;理解私网&#xf…

MySQL---存储过程详解

目录 一、介绍 二、基础语法 三、变量 四、流程控制 五、参数 六、游标 七、条件处理程序 八、存储函数 一、介绍 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合&#xff0c;调用存储过程可以简化应用开发人员的很多工作&#xff0c;减少数据在数据库和…

科技引领趋势:3D元宇宙展厅在各行业中的应用及其未来展望

随着技术的不断进步&#xff0c;3D元宇宙展厅正逐渐成为各行各业展示产品的新选择。相较于传统的线下展厅&#xff0c;3D元宇宙展厅以其独特的优势&#xff0c;为产品展示和品牌推广提供了全新的可能性。 一、虚拟与现实的完美融合 3D元宇宙展厅是指在虚拟世界中构建的三维展览…

I/O(输入/输出流的概述)

文章目录 前言一、流的概述二、输入/输出流 1.字节/字符输入流2.字节/字符输出流总结 前言 在变量、数组和对象中储存的数据是暂时的&#xff0c;程序结束后它们就会丢失。如果想要永久地储存程序创建的数据&#xff0c;需要将其保存在磁盘文件中&#xff0c;这样就可以在程序中…

Java框架安全篇--Shiro-550漏洞

Java框架安全篇--Shiro-550漏洞 Shiro反序列化源码可以提取&#xff1a; https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4 JAVA反序列化就不说了&#xff0c;可以参考前面文章 https://blog.csdn.net/m0_63138919/article/details/136751184 初始Apache Sh…

OC 技术 苹果内购

一直觉得自己写的不是技术&#xff0c;而是情怀&#xff0c;一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的&#xff0c;希望我的这条路能让你们少走弯路&#xff0c;希望我能帮你们抹去知识的蒙尘&#xff0c;希望我能帮你们理清知识的脉络&#xff0…

【Linux】-Linux下的编辑器Vim的模式命令大全及其自主配置方法

目录 1.简单了解vim 2.vim的模式 2.1命令模式 2.2插入模式 2.3底行模式 3.vim各模式下的命令集 3.1正常&#xff08;命令模式下&#xff09; 3.1.1光标定位命令 3.1.2 复制粘贴 3.1.3 删除 3.1.4 撤销 3.1.5大小写转换 3.1.6替换 「R」&#xff1a;替换光标所到之处的字符&…

使用llamafile 构建本地大模型运用

安装 https://github.com/Mozilla-Ocho/llamafile 下载 大模型文件&#xff0c;选择列表中任意一个 wget https://huggingface.co/jartine/llava-v1.5-7B-GGUF/resolve/main/llava-v1.5-7b-q4.llamafile?downloadtrue https://github.com/Mozilla-Ocho/llamafile?tabre…

Element UI中日期选择日(date-picker)等其他选择器下拉显示错位、位置错误解决

省流版 给选择器加上唯一key&#xff08;下面的想看就看&#xff09; 问题复现 需求是用一个下拉切换时间维度的选择&#xff0c;分别为年度、季度、月度&#xff0c;但是开发的时候发现&#xff0c;当切换的时候&#xff0c;视图可正常切换&#xff0c;但点击选择时却发现选…

基于nginx 动态 URL反向代理的实现

背景&#xff1a; 我们在项目中在这样一个场景&#xff0c;用户需要使用固定的软件资源&#xff0c;这些资源是以服务器或者以容器形式存在的。 资源以webAPI方式在内网向外提供接口&#xff0c;资源分类多种类型&#xff0c;每种类型的资源程序和Wapi参数都一样。这些资源部属…

STL —— string(3)

目录 1. 使用 1.1 c_str() 1.2 find() & rfind() 1.3 substr() 1.4 打印网址的协议域名等 1.5 find_first_of() 2. string() 模拟实现 2.1 构造函数的模拟实现 2.2 operator[] 和 iterator 的模拟实现 2.3 push_back() & append() & 的模拟实现 2.4 ins…

sqlite3嵌入式开发板命令行方式使用

如何在编译嵌入式版本的sqlite3&#xff0c;请看我上一篇文章 sqlite3 交叉编译-CSDN博客 一、sqlite3命令行方式使用 假如我将编译好的嵌入式的sqlite3放置在如下路径&#xff1a; 进入bin目录进行操作 1.运行sqlite3 运行sqlite3有两种方式 1&#xff09;直接在内存里面…

零拷贝技术、常见实现方案、Kafka中的零拷贝技术的使用、Kafka为什么这么快

目录 1. 普通拷贝 2. 数据拷贝基础过程 2.1 仅CPU方式 2.2 CPU&DMA方式 3.普通模式数据交互 4. 零拷贝技术 4.1 出现原因 4.2 解决思路 4.2.1 mmap方式 4.2.2 sendfile方式 4.2.3 sendfileDMA收集 4.2.4 splice方式 5. Kafka中使用到的零拷贝技术 参考链接 本…

Intellij IDEA构建Android开发环境

Intellij IDEA创建项目时没有Android的选项 进设置&#xff08;Intellij IDEA - Settings - Plugins &#xff09; 再次创建项目可以看到Android的选项 解决Android导入项目时Gradle下载速度慢/超时/失败

OpenHarmony内核编程实战

在正式开始之前&#xff0c;对于刚接触OpenHarmony的伙伴们&#xff0c;面对大篇幅的源码可能无从下手&#xff0c;不知道怎么去编码写程序&#xff0c;下面用一个简单的例子带伙伴们入门。 ▍任务 编写程序&#xff0c;让开发板在串口调试工具中输出”Hello&#xff0c;Open…

java Web会议信息管理系统 用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 jsp 会议信息管理系统是一套完善的web设计系统&#xff0c;对理解JSP java SERLVET mvc编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&am…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

一周是一年的2%

今天读到阮一峰的293期周刊&#xff0c;其中有句话很让我震动——“一周是一年的2%”。 过去的时间里&#xff0c;我都没有在意时间的流逝&#xff0c;过的好的时候就觉得一周过的好快&#xff0c;周三一过这周也就过去了&#xff0c;过的不好的时候就感觉很漫长。 确实&…

C# wpf 嵌入hwnd窗口

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口&#xff08;本章&#xff09; 第二章 嵌入WinForm控件 第三章 嵌入WPF控件 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现1、继承HwndHost2、实现抽象方法3、xaml中使用HwndHost控件 二、具体实现1、Win32窗口2、HwndSource窗…

【Python】搭建 Python 环境

目 录 一.安装 Python二.安装 PyCharm 要想能够进行 Python 开发&#xff0c;就需要搭建好 Python 的环境 需要安装的环境主要是两个部分&#xff1a; 运行环境: Python开发环境: PyCharm 一.安装 Python (1) 找到官方网站 (2) 找到下载页面 选择 “Download for Windows”…