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.hqwc.cn/news/576632.html

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

相关文章

本地Navicat连接MySQL时报错1142解决办法

本地Navicat连接MySQL时报错1142解决办法&#xff1a; 1&#xff0c;使用root登录 2&#xff0c;使用下面SQL查询权限 use mysql; SELECT * FROM user WHERE usernacos;

【SpringBoot从入门到精通】01_SpringBoot概述

一、Spring与SpringBoot 1.1 Spring Spring 是一款目前主流的 Java EE 轻量级开源框架&#xff0c;是 Java 世界最为成功的框架之一。Spring 由“Spring 之父”Rod Johnson(罗宾约翰逊) 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。 广义…

Java中有哪些容器(集合类)?

Java中的集合类主要由Collection和Map这两个接口派生而出&#xff0c;其中Collection接口又派生出三个子接 口&#xff0c;分别是Set、List、Queue。所有的Java集合类&#xff0c;都是Set、List、Queue、Map这四个接口的实现 类&#xff0c;这四个接口将集合分成了四大类&#…

洛谷 P1379 八数码难题

代码如下&#xff1a; #include<bits/stdc.h> using namespace std; struct node{string s;int pos; }star,en; map<string,int>mp[2]; queue<node>q[2]; int main(){cin>>star.s;en.s"123804765";for(int i0;i<9;i){if(star.s[i]0) sta…

pygame 3d三角形沿y轴旋转后 透视投影在屏幕上

import pygame from pygame.locals import * import sys import mathpygame.init()width, height 800, 600 screen pygame.display.set_mode((width, height))vertices [(0, 100, 1), (100, 200, 0), (300, 100, 1)]angle 0 rotation_speed 2 # 可根据需要调整旋转速度 c…

工业镜头常用参数之实效F(Fno.)和像圈

Fno. 工业镜头中常用到的参数F&#xff0c;有时候用F/#&#xff0c;Fno.来表示&#xff0c;指的是镜头通光能力的参数。它可用镜头焦距及入瞳直径来表示&#xff0c;也可通过镜头数值孔径&#xff08;NA&#xff09;和光学放大倍率&#xff08;β&#xff09;来计算。有效Fno.…

Maven配置国内镜像-阿里云仓库镜像

使用自己安装maven环境时&#xff1a; 打开解压目录下conf/settings.xml文件 使用Idea自带的Maven时&#xff1a; 打开Idea安装路径\plugins\maven\lib\maven3\conf\settings.xml文件 在mirrors节点中加入如下配置&#xff1a; <!-- 加入如下mirror节点 使用国内阿里云仓…

Spring Aop 源码解析(下)

ProxyFactory选择cglib或jdk动态代理原理 ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术: config就是ProxyFactory对象,把自己传进来了,因为ProxyFactory继承了很多类,其中一个父类就是ProxyConfig // config就是ProxyFactory对象// 是不是…

销售的业绩和合同无法统一管理可以通过系统实现吗?

这个问题我们在日常管理中也遇到过&#xff0c;在没有使用软件之前&#xff0c;合同原件没有专人负责打理&#xff0c;销售人员签了合同后&#xff0c;直接把原件随手放在柜子里&#xff0c;或者把数据记录到excel表中。 但是每个人的工作习惯不一样&#xff0c;记录的表格也不…

堆的应用(堆排序,TOP-K问题)详细讲解

所有人都关心我飞的高不高&#xff0c;只有我妈关心我翅膀硬不硬 一、堆的应用 1. 堆排序 1.1 建堆 1.2 利用堆删除思想来进行排序 2.TOP-K问题 二、完结撒❀ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–…

第二十一章 Jquery ajax

文章目录 1. jquery下载2. jquery的使用3. jquery页面加载完毕执行4. jquery属性控制6. 遍历器 2. ajax1. 准备后台服务器2. ajax发送get请求3. ajax发送post请求 1. jquery下载 点击下载 稳定版本1.9 2. jquery的使用 存放到html文件的同级目录 3. jquery页面加载完毕执行…

C语言数据结构基础——排序

目录 1.插入排序 2.冒泡排序 3. 堆排序 4.希尔排序 5.直接选择排序 6.快速排序☆☆ 6.1快速排序基础 6.2关于快速排序的时间复杂度 6.3随机数法和三数取中法 6.4其他的单趟实现方法 6.4.1挖坑法 6.4.2前后指针版快速排序☆ 6.4.3非递归实现快排☆ 7.归并排序 7.1递归…