Elasticsearch的使用教程

news/2024/10/23 18:10:11/

Elasticsearch简介

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,Elasticsearch 会集中存储您的数据,让您飞快完成搜索,微调相关性,进行强大的分析,并轻松缩放规模。

Elasticsearch的安装

下载安装包

下载Elasticsearch7.17.3版本的zip包,并解压到指定目录,下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-17-3
在这里插入图片描述

安装中文分词器

安装中文分词器,注意下载与Elasticsearch对应的版本,下载地址
https://github.com/medcl/elasticsearch-analysis-ik/releases

下载完成后解压

下载完成后解压到Elasticsearch的plugins目录下
在这里插入图片描述
运行bin目录下的elasticsearch.bat启动Elasticsearch服务。
在这里插入图片描述
访问 http://localhost:9200/ 出现这个界面,表示启动成功
在这里插入图片描述

安装Kibana

作为Elasticsearch 的客户端访问
下载Kibana,作为访问Elasticsearch的客户端,请下载7.17.3版本的zip包,并解压到指定目录,下载地址:https://www.elastic.co/cn/downloads/past-releases/kibana-7-17-3
在这里插入图片描述

运行bin目录下的kibana.bat,启动Kibana服务;
打开Kibana的用户界面,访问地址:http://localhost:5601
在这里插入图片描述

相关概念

● Near Realtime(近实时):Elasticsearch是一个近乎实时的搜索平台,这意味着从索引文档到可搜索文档之间只有一个轻微的延迟(通常是一秒钟)。
● Cluster(集群):群集是一个或多个节点的集合,它们一起保存整个数据,并提供跨所有节点的联合索引和搜索功能。每个集群都有自己的唯一集群名称,节点通过名称加入集群。
● Node(节点):节点是指属于集群的单个Elasticsearch实例,存储数据并参与集群的索引和搜索功能。可以将节点配置为按集群名称加入特定集群,默认情况下,每个节点都设置为加入一个名为elasticsearch的群集。
● Index(索引):索引是一些具有相似特征的文档集合,类似于MySql中数据库的概念。
● Type(类型):类型是索引的逻辑类别分区,通常,为具有一组公共字段的文档类型,类似MySql中表的概念。注意:在Elasticsearch 6.0.0及更高的版本中,一个索引只能包含一个类型。
● Document(文档):文档是可被索引的基本信息单位,以JSON形式表示,类似于MySql中行记录的概念。
● Shards(分片):当索引存储大量数据时,可能会超出单个节点的硬件限制,为了解决这个问题,Elasticsearch提供了将索引细分为分片的概念。分片机制赋予了索引水平扩容的能力、并允许跨分片分发和并行化操作,从而提高性能和吞吐量。
● Replicas(副本):在可能出现故障的网络环境中,需要有一个故障切换机制,Elasticsearch提供了将索引的分片复制为一个或多个副本的功能,副本在某些节点失效的情况下提供高可用性。

简单操作

通过Kibana的Dev Tools功能,我们可以操作Elasticsearch;
在这里插入图片描述

索引操作

创建索引并查看

PUT /customer
GET /_cat/indices?v

在这里插入图片描述
删除索引并查看

DELETE /customer
GET /_cat/indices?v

类型操作

首先要导入一批数据

 https://github.com/macrozheng/mall-learning/blob/teach/document/json/accounts.json 
POST /bank/account/_bulk

查看文档类型的操作

GET /bank/_mapping

在索引中添加文档

PUT /customer/doc/1
{"name": "John Doe"
}

查看索引中的文档

GET /customer/doc/1

修改索引中的文档

POST /customer/doc/1/_update
{"doc": { "name": "Jane Doe" }
}

删除索引中的文档

DELETE /customer/doc/1

数据搜索

查询表达式(Query DSL)是一种非常灵活又富有表现力的查询语言,Elasticsearch使用它可以以简单的JSON接口来实现丰富的搜索功能,下面的搜索操作都将使用它。

数据导入

首先要导入一批数据

 https://github.com/macrozheng/mall-learning/blob/teach/document/json/accounts.json 
POST /bank/account/_bulk

搜索入门

最简单的搜索,使用match_all来表示,例如搜索全部

GET /bank/_search
{"query": { "match_all": {} }
}

在这里插入图片描述

分页搜索,from表示偏移量,从0开始,size表示每页显示的数量

GET /bank/_search
{"query": { "match_all": {} },"from": 0,"size": 10
}

搜索排序,使用sort表示,例如按balance字段降序排列;

GET /bank/_search
{"query": { "match_all": {} },"sort": { "balance": { "order": "desc" } }
}

搜索并返回指定字段内容,使用_source表示,例如只返回account_number和balance两个字段内容:

GET /bank/_search
{"query": { "match_all": {} },"_source": ["account_number", "balance"]
}

条件搜索

条件搜索,使用match表示匹配条件,例如搜索出account_number为20的文档

GET /bank/_search
{"query": {"match": {"account_number": 20}}
}

短语匹配搜索,使用match_phrase表示,例如搜索address字段中同时包含mill和lane的文档:

GET /bank/_search
{"query": {"match_phrase": {"address": "mill lane"}}
}

组合搜索

组合搜索,使用bool来进行组合,must表示同时满足,例如搜索address字段中同时包含mill和lane的文档;

GET /bank/_search
{"query": {"bool": {"must": [{ "match": { "address": "mill" } },{ "match": { "address": "lane" } }]}}
}

组合搜索,should表示满足其中任意一个,搜索address字段中包含mill或者lane的文档;

GET /bank/_search
{"query": {"bool": {"should": [{ "match": { "address": "mill" } },{ "match": { "address": "lane" } }]}}
}

组合搜索,must_not表示同时不满足,例如搜索address字段中不包含mill且不包含lane的文档;

GET /bank/_search
{"query": {"bool": {"must_not": [{ "match": { "address": "mill" } },{ "match": { "address": "lane" } }]}}
}

组合搜索,组合must和must_not,例如搜索age字段等于40且state字段不包含ID的文档;

GET /bank/_search
{"query": {"bool": {"must": [{ "match": { "age": "40" } }],"must_not": [{ "match": { "state": "ID" } }]}}
}

过滤搜索

搜索过滤,使用filter来表示,例如过滤出balance字段在20000~30000的文档;

GET /bank/_search
{"query": {"bool": {"must": { "match_all": {} },"filter": {"range": {"balance": {"gte": 20000,"lte": 30000}}}}}
}

参考资料https://www.elastic.co/guide/en/elasticsearch/reference/7.17/getting-started.html

Spring Data Elasticsearch

Spring Data Elasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。

常用注解

在这里插入图片描述
其中常用的FieldType类型有如下几种:

public enum FieldType {Auto("auto"), //自动判断字段类型Text("text"), //会进行分词并建了索引的字符类型Keyword("keyword"), //不会进行分词建立索引的类型Long("long"), //Integer("integer"), //Short("short"), //Byte("byte"), //Double("double"), //Float("float"), //Date("date"), //Boolean("boolean"), //Object("object"), //Nested("nested"), //嵌套对象类型Ip("ip"), //
}

SpringData 方式的数据操作

  • 继承ElasticsearchRepository接口可以获得常用的数据操作方法;
  • 在这里插入图片描述

可以使用衍生查询,在接口中直接指定查询方法名称便可查询,无需进行实现,如商品表中有商品名称、标题和关键字,直接定义以下查询,就可以对这三个字段进行全文搜索。

/*** @description 商品ES操作类*/
public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {/*** 搜索查询** @param name              商品名称* @param subTitle          商品标题* @param keywords          商品关键字* @param page              分页信息* @return*/Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);
}

通过@Query注解可以使用Elasticsearch的原生DSL语句进行查询;

/*** @description 商品ES操作类*/
public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {@Query("{"bool" : {"must" : {"field" : {"name" : " ? 0"}}}}")Page<EsProduct> findByName(String name, Pageable pageable);
}

整合Elasticsearch商品搜索

整理依赖配置

  • 在pom.xml中添加相关依赖;
<!--Elasticsearch相关依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 修改application.yml配置文件,在spring节点下添加Elasticsearch相关配置;
spring:data:elasticsearch:repositories:enabled: true # 开启ES仓库配置,自动为仓库接口生成实现类elasticsearch:uris: http://localhost:9200 # ES的连接地址及端口号

实现商品搜索功能

添加商品文档对象EsProduct

不需要中文分词的字段设置成Keyword类型,需要中文分词的设置成Text类型,并设置分词器为ik_max_word;

/*** @description 搜索商品的信息*/
@Data
@EqualsAndHashCode
@Document(indexName = "pms")
@Setting(shards = 1,replicas = 0)
public class EsProduct implements Serializable {private static final long serialVersionUID = -1L;@Idprivate Long id;@Field(type = FieldType.Keyword)private String productSn;private Long brandId;@Field(type = FieldType.Keyword)private String brandName;private Long productCategoryId;@Field(type = FieldType.Keyword)private String productCategoryName;private String pic;@Field(analyzer = "ik_max_word",type = FieldType.Text)private String name;@Field(analyzer = "ik_max_word",type = FieldType.Text)private String subTitle;@Field(analyzer = "ik_max_word",type = FieldType.Text)private String keywords;private BigDecimal price;private Integer sale;private Integer newStatus;private Integer recommandStatus;private Integer stock;private Integer promotionType;private Integer sort;@Field(type =FieldType.Nested)private List<EsProductAttributeValue> attrValueList;
}

继承ElasticsearchRepository接口

这样就拥有了一些基本的Elasticsearch数据操作方法,同时定义了一个衍生查询方法;

/*** @description 商品ES操作类*/
public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {/*** 搜索查询** @param name              商品名称* @param subTitle          商品标题* @param keywords          商品关键字* @param page              分页信息* @return*/Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);}

添加EsProductService,定义好ES的操作方法

/*** @description 商品搜索管理Service*/
public interface EsProductService {/*** 从数据库中导入所有商品到ES*/int importAll();/*** 根据id删除商品*/void delete(Long id);/*** 根据id创建商品*/EsProduct create(Long id);/*** 批量删除商品*/void delete(List<Long> ids);/*** 根据关键字搜索名称或者副标题*/Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize);}

添加EsProductService接口的实现类EsProductServiceImpl;

/*** @description 搜索商品管理Service实现类*/
@Service
public class EsProductServiceImpl implements EsProductService {private static final Logger LOGGER = LoggerFactory.getLogger(EsProductServiceImpl.class);@Autowiredprivate EsProductDao productDao;@Autowiredprivate EsProductRepository productRepository;@Overridepublic int importAll() {List<EsProduct> esProductList = productDao.getAllEsProductList(null);Iterable<EsProduct> esProductIterable = productRepository.saveAll(esProductList);Iterator<EsProduct> iterator = esProductIterable.iterator();int result = 0;while (iterator.hasNext()) {result++;iterator.next();}return result;}@Overridepublic void delete(Long id) {productRepository.deleteById(id);}@Overridepublic EsProduct create(Long id) {EsProduct result = null;List<EsProduct> esProductList = productDao.getAllEsProductList(id);if (esProductList.size() > 0) {EsProduct esProduct = esProductList.get(0);result = productRepository.save(esProduct);}return result;}@Overridepublic void delete(List<Long> ids) {if (!CollectionUtils.isEmpty(ids)) {List<EsProduct> esProductList = new ArrayList<>();for (Long id : ids) {EsProduct esProduct = new EsProduct();esProduct.setId(id);esProductList.add(esProduct);}productRepository.deleteAll(esProductList);}}@Overridepublic Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {Pageable pageable = PageRequest.of(pageNum, pageSize);return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable);}}

添加EsProductController定义接口。

/*** @description 搜索商品管理Controller*/
@Controller
@Api(tags = "EsProductController")
@Tag(name = "EsProductController", description = "搜索商品管理")
@RequestMapping("/esProduct")
public class EsProductController {@Autowiredprivate EsProductService esProductService;@ApiOperation(value = "导入所有数据库中商品到ES")@RequestMapping(value = "/importAll", method = RequestMethod.POST)@ResponseBodypublic CommonResult<Integer> importAllList() {int count = esProductService.importAll();return CommonResult.success(count);}@ApiOperation(value = "根据id删除商品")@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)@ResponseBodypublic CommonResult<Object> delete(@PathVariable Long id) {esProductService.delete(id);return CommonResult.success(null);}@ApiOperation(value = "根据id批量删除商品")@RequestMapping(value = "/delete/batch", method = RequestMethod.POST)@ResponseBodypublic CommonResult<Object> delete(@RequestParam("ids") List<Long> ids) {esProductService.delete(ids);return CommonResult.success(null);}@ApiOperation(value = "根据id创建商品")@RequestMapping(value = "/create/{id}", method = RequestMethod.POST)@ResponseBodypublic CommonResult<EsProduct> create(@PathVariable Long id) {EsProduct esProduct = esProductService.create(id);if (esProduct != null) {return CommonResult.success(esProduct);} else {return CommonResult.failed();}}@ApiOperation(value = "简单搜索")@RequestMapping(value = "/search/simple", method = RequestMethod.GET)@ResponseBodypublic CommonResult<CommonPage<EsProduct>> search(@RequestParam(required = false) String keyword,@RequestParam(required = false, defaultValue = "0") Integer pageNum,@RequestParam(required = false, defaultValue = "5") Integer pageSize) {Page<EsProduct> esProductPage = esProductService.search(keyword, pageNum, pageSize);return CommonResult.success(CommonPage.restPage(esProductPage));}
}

http://www.ppmy.cn/news/1426182.html

相关文章

webpack源码分析——enhanced-resolve库之getType、normalize、join和cachedJoin函数

一、PathType 路径类型 const PathType Object.freeze({Empty: 0, // 空Normal: 1, // 默认值Relative: 2, // 相对路径AbsoluteWin: 3, // win 下的绝对路径AbsolutePosix: 4, // posix 下的绝对路径Internal: 5 // enhanced-resolve 内部自定义的一种类型&#xff0c;具体是…

【redis】hash和list常用命令

hash类型 Redis自身已经是键值对结构了。Redis自身的键值对就是通过哈希的方式来组织的。 把key这一层组织完成之后,到了value这一层。value的其中一种类型还可以再是哈希。哈希类型中的映射关系通常称为field-value,用于区分Redis整体的键值对(key-value)。注意这里的 value…

循环双链表的操作

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一个裂缝都是为透出光而努力&#…

【深度学习实战(12)】训练之模型参数初始化

在深度学习模型的训练中&#xff0c;权重的初始值极为重要。一个好的初始值&#xff0c;会使模型收敛速度提高&#xff0c;使模型准确率更精确。一般情况下&#xff0c;我们不使用全0初始值训练网络。为了利于训练和减少收敛时间&#xff0c;我们需要对模型进行合理的初始化。 …

记录一个hive中因没启yarn导致的spark引擎跑insert语句的报错

【背景说明】 刚在hive中配置了Spark引擎&#xff0c;在进行Hive on Spark测试时报错&#xff0c; 报错截图如下&#xff1a; [atguiguhadoop102 conf]$ hive which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8.0_212/bin:/opt/mod…

前端开发与html学习笔记

一、前端开发概述 前端开发&#xff1a;也叫做web前端开发&#xff0c;它指的是基于web的互联网产品的页面(也可叫界面)开发及功能开发互联网产品&#xff1a;指网站为满足用户需求而创建的用于运营的功能及服务&#xff0c;百度搜索、淘宝、QQ、微博、网易邮箱等都是互联网产…

如何搭建线下陪玩系统(本地伴游、多玩圈子)APP小程序H5多端前后端源码交付,支持二开!

一、卡顿的优化方法 1、对陪玩系统源码中流媒体传输的上行进行优化&#xff0c;通过提升推流端的设备性能配置、推流边缘CDN节点就近选择等方式解决音视频数据源流的卡顿。 2、对陪玩系统源码中音视频数据的下载链路进行优化&#xff0c;通过选择更近更优质的CDN边缘节点来减少…

WordPress 多站点切换域名完整指南:详细步骤和注意事项

因为公司的需要&#xff0c;需要对 WordPress 多站点进行域名切换, 一开始我也找了相关的方案和教程&#xff0c;但是很可惜&#xff0c;国内这一块网上的资料几乎为0&#xff0c;所以我把实现的过程写了一篇文章分享出来&#xff0c;为后来的人铺路。 开始之前&#xff0c;先…