ElasticSearch7.x入门文档!SpringBoot项目如何对接ElasticSearch?Spring-data-elasticsearch-2.7.5新版api全网唯一使用教程!

由于公司新开项目,需要接入ElasticSearch,而公司内部配置ElasticSearch为新版7.17.0,自己之前也没有学习过ElasticSearch的使用,就直接使用了新版的Spring-data-elastic-2.7.5框架对接,这时候才发现新版spring-data-elasticsearch的api较之老版有很大的改动,而且还有一些坑爹的漏洞,网络上相关的文档也是少之又少,于是在此总结一下个人学习中的一些经验,供各位参考,个人能力有限,只是总结一些基础的使用,错误之处应当不少,还望各位积极指出。

1. 核心概念

ElasticSearch是基于Lucene搜索引擎开发的分布式搜索和分析引擎,其内部核心原理可参考我上一篇Lucene的学习笔记:Lucene笔记。其关键概念有一下几点。

ES数据结构

ES的数据结构与常见的数据库结构类似,只是名称概念不同。

  1. Index,翻译过来是索引,但是其本质类似于数据库中的表或者库,因为ES没有特定的数据结构,所以对数据没有表粒度的拆分,Index作为存储数据的库直接存储所有数据。
  2. Document,文档,可对应于数据库表中的每一行数据,每一次往ES 中插入一条数据,就视作插入一个文档。
  3. Field,域。类似于数据库中字段的概念,一个域就是一个约定的字段,但是插入创建Index时没有指定的域也不会报错

倒排索引

既然学习ES,我们首先就得知道ES使用来干嘛的。众所周知,ES是用于大数据量情况下的条件搜索服务,主要功能是基于内容搜索匹配的数据,也就是说,ES是专供于模糊搜索的。这对于结构化数据多用于精确搜索的概念就恰恰是一体两面性。Mysql利用结构化数据,常用于提供精确化的搜索,找到内容, 其核心逻辑体现类似于 id -> content,利用Id查询到唯一内容;而ES利用倒排索引,通过查询条件找到匹配的数据id集合,再找到相匹配的数据,核心逻辑类似于 keyWord -> ids,通过关键词找到大量包含片段的Id集合。
在这个过程中,我们就有了倒排索引的概念,在ES存储数据的同时,我们将数据每个域的内容利用分词器进行切分,分成不同的片段内容——即关键词,然后关键词作为id,文档id作为value存入倒排索引库。
比如我们有一个数据(id为es内部的文档id)

{“id:1,"name" : "苹果手机”
}

在插入es时,我们就会根据配置分词器的规则,对name字段进行分词,分为“苹果”和“手机”,那么在es里就有这样的倒排索引结构:

name: {
苹果:[1]
手机: [1]
“苹果手机” :[1]}

然后我们再插入一条

{“id:2,"name" : "苹果电脑”
}

此时我们倒排索引的结构就会变成

name:{苹果:[1,2]手机:[1]电脑:[2]“苹果手机” :[1]“苹果电脑“ :[2]
}

这个时候如果我们搜索“苹果”,倒排索引里面就会查询到id集合“1,2“,然后根据id的到最终的数据,这个过程相当于两次主键查询,速度相对于Mysql的模糊查询就是非常快的。

分词器

分词器即我们存储查询时候的分词逻辑,即怎么分词,每个分词器的分词效果可能都不相同。默认的分词器对于中文的分词一般是一个字一分,对于“苹果手机”可能会分词成“苹”“果”“手”“机”四个关键词,生成四个倒排索引,而中文分词器可能就会分成“苹果”“手机”"苹果手机”三个关键词。
因此,在查询的时候,我们必须保证与入库的分词器一致,当你入库选择默认生成了上述四个关键词后,而我们查询时却是用了IK分词器,那么当我们用“苹果”“和”手机“两个关键字去倒排索引库里查询对应的id时,我们无法得到结果,反而搜索不到数据。

2 ElasticSearch的部署

作为一个专业的程序员,自然是以Linux为例来讲解啦,没有自己的服务器的话,阿里云服务器新用户优惠可了解一下。

  1. 第一步,创建ES的操作账号,这一点非常重要!!!
    作为我三番五次踩的一个大坑,这个重点强调。ES内部的设置,你是无法用root账户启动es的。所以首先创建一个ES的用户,剩下后续一切数据权限的困扰。
useradd user-es #创建用户
passwd espassword #设置密码
  1. 第二步,下载ES安装包
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.0-linux-x86_64.tar.gz
  1. 第三步,解压
tar -zxvf elasticsearch-7.17.0-linux-x86_64.tar.gz -C /usr/local/es
  1. 修改配置项./config/elasticsearch.yml,主要有这么几个点要注意
cluster.name: 设置集群的名字
node.name: 设置当前节点的名字
network.host: 0.0.0.0 (允许访问的ip,需要打开配置成0.0.0.0代表支持任意ip访问)
http.port: 9200 端口号
cluster.initial_master_nodes: ["主节点名称"] (单机部署时也需要配置,写入当前节点的名称)
  1. 然后进入./bin目录下,后台启动,访问对应9200端口号,如果有返回代表启动成功。
./elasticsearch -d # -d代表后台启动
  1. 安装kibana作为控制台,安装比较简单,一样的下载安装包,解压,配置中修改连接的地址为es服务器的ip和端口号。同样操作用es的账户
server.port: 5601         #kibana端口
server.host: "0.0.0.0"   #所有主机都能访问,或者也可以指定一个ip
elasticsearch.hosts: "http://es服务公网IP:9200"     #配置es

3 ElasticSearch的基础使用

  1. 创建Index
put /indexName
{{"settings" : {"number_of_shards" : 3, //分片数,详情可查询lucene文档"number_of_replicas" : 1  // 文档备份数}
}
}
  1. 删除索引
DELETE /indexName
  1. 查看索引下文档
GET /indexName/_doc/_search
  1. 修改索引映射关系
PUT /indexName/_mapping
{"properties" : {"域" : {"type" : "text", // 域类型"index": true,// 是否索引,即是否支持跟据该字段查询"store": true, //是否存储该数据,即该数据是否可被查询到"analyzer": "分词器" //配置字段分词器}}
}
  1. 索引下查询文档
POST /indexName/_search
{"query": {"bool": { // bool类似于一个括号,括号内部的所有判断组合成一个"should": [ // must 必须 should 或者 must_not 必须不 filter 范围过滤 (must和sholud不能在同一层级使用,必须将should用bool组装后,外层和must结合使用{"match": { // match : 分词后的左右模糊查询, match_phrase :不分词的左右模糊查询"brand": "apple"}},{"match_phrase": { // 对于集合的查询,一般使用不分词的左右模糊查询  "areas": "中国"}}],"filter": { // 范围过滤"range": {"price": {"gt": 1000, // 大于 "lt": 2000  // 小于}}}}},"from": 0,  // 起始下标"size": 10,  // 分页大小"sort": [{"time": "desc"  // 排序字段和方式}]
}
  1. 全量修改指定文档
@PUT /indexName/_doc/指定docId
{"key1" : "value1","key2" : "value1","key3" : "value1"....
}
  1. 修改指定字段
POST /indexName/_update/指定docId
{"doc" : {"要修改的key" : "修改后的value"}
}
  1. 删除数据
DELETE /indexName/_doc/删除数据的ID
  1. 聚合查询
POST /indexName/_search
{"aggs" : { // 聚合操作"brand_group" : { // 分组名, 随意"terms" : { // 分组 avg 平均值"field" : "price" // 分组字段}}}
}

这些就是ES操作时候的基础语法,一般可以在Kibana的控制台上面进行操作。或者也可以直接使用HTTP请求工具直接访问es进行操作。虽然语法初见可能觉得繁琐又生硬,但是习惯后其实也比较清晰。个人能力有限,只把自己常用的列举出来,欢迎大家补充。

4. SpringBoot项目对接ElasticSearch

接下来就是喜闻乐见的SpringBoot对接ElasticSearch的操作了,篇幅有限,我又不在这边赘述ElasticSearch的原生客户端了,但是建议有兴趣的同学可以去学习了解一下,对于认识ElasticSearch的Java客户端非常有帮助,springdata也是基于这些个客户端进行的封装。

  1. 第一步引入SpringBootDataElastic的依赖,记住这里需要在POM文件中<properties>中指定对应的ElasticSearch版本号(在传递依赖中会根据这里的制定的组件版本配置对应的依赖版本,如果没有配置可能会导致引入的依赖版本不对
<properties><spring-boot.version>2.7.5</spring-boot.version><elasticsearch.version>7.17.0</elasticsearch.version>
</properties><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  1. 在新版的SpringData中省去了客户端Config的配置,只需要在配置文件中配置对应的ElasticSearch地址即可完成配置。
spring:elasticsearch:uris:IP:9200
  1. 在代码中配置对应的索引DO,类似于Mybatis配置的POJO对象,在项目启动时会根据这些DO自动在ES中生成对应的索引,并配置相应的映射结构。
package com.talkAboutAll.domain.es;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;import java.util.Map;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(indexName = "phone", shards = 3, replicas = 1)
public class Phone {// 必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id"@Idprivate Long id;/*** type : 字段数据类型* analyzer : 分词器类型* index : 是否索引(默认:true)* store: 是否存储*/@Field(type = FieldType.Text,index = true, analyzer = "ik_max_word")private String name;@Field(type=FieldType.Keyword)private String brand;@Field(type = FieldType.Double)private Double price;@Field(type = FieldType.Object)private Map<String, String> map;
}
  1. 根据对应的Bean,创建对应的DAO对象,该DAO对象自带索引下文档的增删改查方法,可以在Dao中自定义方法,其使用类似于MybatisPlus。(PS:新版API中移除了原有的search方法,统一为searchSimilar方法,但是后者必须要指定ID才可以进行查询!于是后续查询我们统一使用ElasticsearchRestTemplate)
package com.talkAboutAll.es.dao;import com.talkAboutAll.domain.es.Phone;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;@Repository
public interface PhoneDao extends ElasticsearchRepository<Phone, Long> {}
  1. 数据新增我们可以使用dao的Save和SaveAll方法,而查询我们要利用倒springdata新版的高级客户端类——ElasticsearchRestTemplate。以下列查询为例:
// 新建查询工具
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();// 组装查询条件
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 组装must条件
boolQuery.must(QueryBuilders.matchPhraseQuery("brand", "苹果"));//不分词左右模糊查询
boolQuery.must(QueryBuilders.matchQuery("name","苹果 华为 小米")); //分词模糊查询// 组装should条件,由于should跟must在同一层级会导致失效,所以需要用bool组装, 再放到must中,逻辑结构类似于 xxx && xxx && ( xxx || xxx)
BoolQueryBuilder bool = QueryBuilders.boolQuery();
bool.should(QueryBuilders.matchQuery("type","手机"));
bool.should(QueryBuilders.matchQuery("type","电脑"));
boolQuery.must(bool);// 范围查询 用到过滤
boolQuery.filter(QueryBuilders.rangeQuery("createTime").gte(xxx).lte(xxx))// 排序字段
FieldSortBuilder sort = new FieldSortBuilder("createTime").order(SortOrder.DESC);// 分页参数 偏移量+页数
PageRequest page = PageRequest.of(0, 100);// 创建索引搜索器
queryBuilder.withQuery(boolQuery).withSorts(sort).withPageable(page);// 执行搜索
SearchHits<Phone> searchResult = elasticsearchRestTemplate.search(queryBuilder.build(), Phone.class);// 获取匹配结果
long totalCount = search.getTotalHits();// 转化为业务对象
List<Phone> phones = searchResult.stream().map(hit -> hit.hit.getContent()).Collectors.toList();

对于基本的查询, 便可套用该类模板,如果涉及加权排序,聚合分组等操作,可学习QueryBuilders的使用,基本也是基于这个类实现的操作。个人能力有限,不再做过多讨论。

ElasticSearch7.x 从部署到开发相关推荐

  1. Windows 7 部署 Android 开发环境傻瓜式教程(Eclipse+ADT)

    我把该教程做成了一个PDF,网速慢的朋友可以在这里下载 http://files.cnblogs.com/vengen/AndroidSetup.zip 准备文件: WIN7 的安装方法与 XP 的安 ...

  2. 白话tensorflow分布式部署和开发

    2019独角兽企业重金招聘Python工程师标准>>> 白话tensorflow分布式部署和开发 博客分类: 深度学习 关于tensorflow的分布式训练和部署, 官方有个英文的文 ...

  3. tengine简单安装_实操丨如何在EAIDK上部署Tengine开发AI应用之物体检测应用入门(C++)...

    前言:近期推出的嵌入式AI系列直播公开课受到广大开发者的喜爱,并收到非常多的反馈信息,其中对如何在EAIDK上面部署Tengine开发AI应用感兴趣的开发者不在少数,我们将分2期以案例实操的形式详细介 ...

  4. SVN 自动部署到开发环境

    使用 hooks 自动将项目部署到开发环境 你要知道的: start-commit 提交前触发事务 pre-commit 提交完成前触发事务 post-commit 提交完成时触发事务 pre-rev ...

  5. Apache Spark1.1.0部署与开发环境搭建 - Mark Lin

    Spark是Apache公司推出的一种基于Hadoop Distributed File System(HDFS)的并行计算架构.与MapReduce不同,Spark并不局限于编写map和reduce ...

  6. docker php composer 使用_如何使用Docker部署PHP开发环境

    本文主要介绍了如何使用Docker构建PHP的开发环境,文中作者也探讨了构建基于Docker的开发环境应该使用单容器还是多容器,各有什么利弊.推荐PHP开发者阅读.希望对大家有所帮助. 环境部署一直是 ...

  7. win10+vscode部署java开发环境

    目录 Java开发插件配置: 调试: 快捷键: 启动配置文件launch.json: 启动配置说明: Launch: Attach: User Setting: 遇到的问题: 参考: Java开发插件 ...

  8. 边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发

    边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发 使用SDK开发真实设备接入服务 着手编写一个温湿度设备接入 准备相关文件及目录 脚本可选,用于单文件编译测试 编写温湿度设备接 ...

  9. [Linux]在Linux上部署Java开发环境笔记(一)-- 补充:Linux下如何手动设置IP及配置DNS服务

    在Linux上部署Java开发环境笔记(一) -- 补充:Linux下如何手动设置IP及配置DNS服务 2010/06/17 有的Linux系统会有网络设置的图形操作界面,比如"红旗Linu ...

最新文章

  1. 3D目标检测论文阅读多角度解析
  2. kafka-2.11-2.3.0版本配置文件参数详解_Kafka版本特性总结
  3. .net采集网页方法大全(5种)
  4. kubernetes-1.11.0集群部署之master集群 (二)
  5. Android总结之链式调用(方法链)
  6. python--Websocket实现, 加密 sha1,base64
  7. .Net6种成员的可访问性
  8. python中的[1:]、[::-1]、X[:,m:n]和X[1,:]
  9. cobbler装系统
  10. idea64.exe.vmoptions 参数意义
  11. mschart控件使用详解
  12. 手机运作html实现弹窗,html5实现手机弹窗留言对话框(摘)
  13. 什么是驻点和拐点_驻点、极值点、拐点、鞍点的区别与联系
  14. 计算机二级函数lookup函数,Lookup函数“0/”结构的详细剖析
  15. python的OOP机制
  16. 什么是HTTO协议?来看!
  17. MySQL pt工具应用
  18. 《查拉图斯特拉如是说》摘抄
  19. c语言字符类型中int表示什么,int表示什么数据类型
  20. 微软官方安装U盘启动盘制作方法教程

热门文章

  1. 捷信总经理Ondrej:愿为中欧企业间的长远发展与互惠共赢而努力
  2. C++项目实战 —— 演讲比赛流程管理系统
  3. 微信小程序 云数据库使用(下)
  4. 关于股息、增发、回购的个人看法
  5. 苹果系列手机清除的文件如何恢复的呢
  6. 02-特征逆推图像实验
  7. 《Essential Linux Device Drivers》中文版第1章
  8. ubuntu安装sougoupinyin[sogoupinyin_2.2.0.0108_amd64.deb]出坑(内附各种失败解决办法)
  9. BIOS设置光盘启动(上.Award bios)
  10. Java程序GUI与JDBC的应用