Java全能学习+面试指南:https://javaxiaobear.cn
1、Elasticsearch概述
1、什么是Elasticsearch
The Elastic Stack, 包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES, ES是一个开源的高扩展的分布式全文搜索引擎,是整个Elastic Stack技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
2、全文搜索引擎
Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。
一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对SQL的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。
基于以上原因可以分析得出,在一些生产环境中,使用常规的搜索方式,性能是非常差的:
-
搜索的数据对象是大量的非结构化的文本数据。
-
文件记录量达到数十万或数百万个甚至更多。
-
支持大量基于交互式文本的查询。
-
需求非常灵活的全文搜索查询。
-
对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。
-
对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。
为了解决结构化数据搜索和非结构化数据搜索性能问题,我们就需要专业,健壮,强大的全文搜索引擎,这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
3、Elasticsearch And Solr
Lucene是Apache软件基金会Jakarta项目组的一个子项目,提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。但Lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来进行应用。
目前市面上流行的搜索引擎软件,主流的就两款:Elasticsearch和Solr,这两款都是基于Lucene搭建的,可以独立部署启动的搜索引擎服务软件。由于内核相同,所以两者除了服务器安装、部署、管理、集群以外,对于数据的操作 修改、添加、保存、查询等等都十分类似。
4、Elasticsearch Or Solr
Elasticsearch和Solr都是开源搜索引擎,那么我们在使用时该如何选择呢?
-
Google 搜索趋势结果表明,与 Solr 相比, Elasticsearch 具有很大的吸引力,但这并不意味着 Apache Solr 已经死亡。虽然有些人可能不这么认为,但 Solr 仍然是最受欢迎的搜索引擎之一,拥有强大的社区和开源支持。
-
与 Solr 相比, Elasticsearch 易于安装且非常轻巧。此外,你可以在几分钟内安装并运行Elasticsearch 。但是,如果 Elasticsearch 管理不当,这种易于部署和使用可能会成为一个问题。基于 JSON 的配置很简单,但如果要为文件中的每个配置指定注释,那么它不适合您。总的来说,如果你的应用使用 的是 JSON ,那么 Elasticsearch 是一个更好的选择。否则,请使用 Solr ,因为它的 schema.xml 和 solrconfig.xml 都有很好的文档记录。
-
Solr 拥有更大,更成熟的用户,开发者和贡献者社区。 ES 虽拥有的规模较小但活跃的用户社区以及不断增长的贡献者社区。Solr贡献者和提交者来自许多不同的组织,而 Elasticsearch 提交者来自单个公司。
-
Solr 更成熟,但 ES 增长迅速,更稳定。
-
Solr 是一个非常有据可查的产品,具有清晰的示例和 API 用例场景。 Elasticsearch 的文档组织良好,但它缺乏好的示例和清晰的配置说明。
那么,到底是Solr 还是 Elasticsearch?
由于易于使用, Elasticsearch 在新开发者中更受欢迎。一个下载和一个命令就可以启动一切。
如果除了搜索文本之外还需要它来处理分析查询, Elasticsearch 是更好的选择
如果需要分布式索引,则需要选择 Elasticsearch 。对于需要良好可伸缩性和 以及 性能分布式环境 Elasticsearch 是更好的选择。
Elasticsearch 在开源日志管理用例中占据主导地位,许多组织在 Elasticsearch 中索引它们的日志以使其可搜索。
如果你喜欢监控和指标,那么请使用Elasticsearch ,因为相对于Solr,Elasticsearch 暴露了更多的关键指标
2、Elasticsearch入门
1、Elasticsearch 安装
1、下载
Elasticsearch 的官方地址: https://www.elastic.co/cn/
下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
Elasticsearch 分为 Linux 和 WindowWindows版本,基于我们主要学习的是 ElasticElasticsearch 的 Java客户端的使用,所以 课程 中使用的是安装较为简便的 WindowWindows版本 。
2、安装
Windows版的 ElasticElasticsearch 的安装很简单,解压即安装完毕,解压后的 ElasticElasticsearch 的 目录结构如下
目录 | 含义 |
---|---|
bin | 可执行脚本目录 |
config | 配置目录 |
jdk | 内置JDK 目录 |
lib | 类库 |
logs | 日志目录 |
modules | 模块目录 |
plugins | 插件目录 |
解压后,进入bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务
注意:
-
9300
端口为 Elastic s earch 集群间组件的通信端口, -
9200
端口为浏览器访问的 http协议 RESTful 端口。
打开浏览器(推荐使用谷歌浏览器),输入地址:http://localhost:9200 ,测试结果
3、问题解决
-
ElasticSearch 是使用 java 开发的,且 7.13.2版本的 ES 需要 JDK 版本 1.8 以上,默认安装包带有 jdk 环境,如果系统配置 JAVA_HOME ,那么使用系统默认的 JDK ,如果没有配置使用自带的 JDK ,一般建议使用系统配置的 JDK 。
-
双击启动窗口闪退,通过路径访问追踪错误,如果是“空间不足”,请修改config/jvm.options 配置文件
设置 JVM 初始内存为 1G 。此值可以设置与 Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存
Xms represents the initial size of total heap space
设置 JVM 最大可用内存为 1G
Xmx represents the maximum size of total heap space
Xms1g Xmx1g
2、基本操作
1、RESTful
REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful 。 Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI(Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET 、 PUT 、 POST 和DELETE 。
在REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET 、 POST 、PUT 、 DELETE ,还可能包括 HEAD 和 OPTIONS 。简单的理解就是,如果想要访问互联网上的资源,就必须向资源所在的服务器发出请求,请求体中必须包含资源的网络路径, 以及对资源进行的操作 增删改查 。
2、Postman安装
如果直接通过浏览器向Elasticsearch 服务器发请求,那么需要在发送的请求中包含HTTP 标准的方法,而 HTTP 的大部分特性且仅支持 GET 和 POST 方法。所以为了能方便地进行客户端的访问,可以使用 Postman 软件 Postman是一款强大 的 网页调试工具,提供功能强大的 Web API 和 HTTP 请求调试。软件功能强大,界面简洁明晰、操作方便快捷,设计得很人性化。 Postman 中文版能够发送任何类型的 HTTP 请求 (GET, POST, PUT..) PUT..),不仅能够表单提交,且可以附带任意类型请求体。
Postman官网: https://www.getpostman.com Postman下载 https://www.getpostman.com/apps
3、数据格式
Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。 为了方便大家理解,我们将 Elastic s earch 里 存储 文档 数据和关系型数据库 MySQL 存储数据的概念进行一个类比
ES里的 Index 可以看做一个库,而 Types 相当于表, Documents 则相当于表的行。这里Types 的概念已经被逐渐弱化, Elasticsearch 6.X 中,一个 index 下已经只能包含一个type Elasticsearch 7.X 中 , Type 的概念已经被删除了。
4、HTTP操作
1、索引操作
1、创建索引
对比关系型数据库,创建索引就等同于创建数据库
在Postman 中,向 ES 服务器发 PUT 请求 http://127.0.0.1:9200/start
请求后,服务器返回响应
" 【响应结果】 : true, # true 操作成功
"shards_ 【分片结果】 : true, # 分片操作成功
" 【索引名称】 : "
# 注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片
如果重复添加索引,会返回错误信息
2、查看索引
在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/_cat/indices?v
这里请求路径中的 _cat 表示查看的意思, indices 表示索引,所以整体含义就是查看当前 ES服务器中的所有索引,就好像 MySQL 中的 show tables 的感觉,服务器响应结果如下
3、查看单个索引
在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/start
查看索引向ES 服务器发送的请求路径和创建索引是一致的。但是 HTTP 方法不一致。这里可以体会一下 RESTful 的意义,请求后,服务器响应结果如下:
{
"start"【索引名】: {
"aliases"【别名】: {},
"mappings"【映射】: {},
"settings"【设置】: {
"index"【设置-索引】: {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards"【设置-索引-主分片数量】: "1",
"provided_name"【名称】: "start",
"creation_date"【创建时间】: "1624440317651",
"number_of_replicas"【设置-索引-副分片数量】: "1",
"uuid"【唯一标识】: "5tI3rmvvQsKJISZ8GDR-YQ",
"version"【设置-索引-版本】: {
"created": "7130299"
}
}
}
}
}
4、删除索引
在Postman 中,向 ES 服务器发 DELETE 请求 http://127.0.0.1:9200/start
重新访问索引时,服务器返回响应:索引不存在
2、文档操作
1、创建文档
索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式
在Postman 中,向 ES 服务器发 POST 请求 http://127.0.0.1:9200/start/doc
此处发送请求的方式必须为POST ,不能是 PUT ,否则会发生错误
{
"_index"【索引】: "start",
"_type"【类型-文档】: "doc",
"_id"【唯一标识】: "iY9GOHoBucAyibLJ1Bbq",#可以类比为 MySQL 中的主键,随机生成
"_version"【版本号】: 1,
"result"【结果】: "created", #这里的 create 表示创建成功
"_shards"【分片】: {
"total"【分片-总数】: 2,
"successful"【分片-成功】: 1,
"failed"【分片-s】: 0
},
"_seq_no": 1,
"_primary_term": 1
}
上面的数据创建后,由于没有指定数据唯一性标识(ID ),默认情况下 ES 服务器会随机生成一个 。
如果想要自定义唯一性标识,需要在创建时指定http://127.0.0.1:9200/start/doc/1 or http://127.0.0.1:9200/start/_doc/1
此处需要注意:如果增加数据时明确数据主键,那么请求方式也可以为PUT
2、查看文档
查看文档时,需要指明文档的唯一性标识,类似于MySQL 中数据的主键查询
在Postman 中,向 ES 服务器发 GET 请求 http://127.0.0.1:9200/start/_doc/1
查询成功后,服务器响应结果:
{
"_index"【索引】: "start",
"_type"【文档类型】: "_doc",
"_id": "1",
"_version": 1,
"_seq_no": 2,
"_primary_term": 2,
"found"【查询结果】: true,# true 表示查找到, false 表示未查找到
"_source"【文档源信息】: {
"title": "小米手机",
"category": "小米",
"images": "www.xiaobear.cn",
"price": 3999.00
}
}
3、修改文档
和新增文档一样,输入相同的URL 地址请求,如果请求体变化,会将原有的数据内容覆盖 在Postman 中,向 ES 服 务器发 POST 请求 http://127.0.0.1:9200/start/_doc/1
请求体内容为:
{
"title":"华为手机",
"category":"小米",
"images":"www.xiaobear.cn",
"price":4999.00
}
修改成功后,服务器响应结果:
{
"_index": "start",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 2,
"result"【结果】: "updated",# updated 表示数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 2
}
4、修改字段
修改数据时,也可以只修改某一给条数据的局部信息
在Postman 中,向 ES 服务器发 POST 请求 http://127.0.0.1:9200/start/_update/1
请求体内容为:
{
"doc": {
"price":5000.00
}
}
修改成功后,服务器响应结果:
根据唯一性标识,查询文档数据,文档数据已经更新
5、删除文档
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。
在Postman 中,向 ES 服务器发 DELETE 请求 http://127.0.0.1:9200/start/_doc/1
删除成功,服务器响应结果:
version:对数据的操作,都会更新版本
删除后再查询当前文档信息
如果删除一个并不存在的文档
6、条件删除文档
一般删除数据都是根据文档的唯一性标识进行删除,实际操作时,也可以根据条件对多条数据进行删除
首先分别增加多条数据:
{
"title":"小米手机",
"category":"小米",
"images":"www.xiaobear.cn",
"price":3999.00
}
{
"title":"华为手机",
"category":"华为",
"images":"www.xiaobear.cn",
"price":3999.00
}
向ES 服务器发 POST 请求 http://127.0.0.1:9200/start/_delete_by_query
请求体内容为:
{
"query":{
"match":{
"price": 3999.00
}
}
}
删除成功后,服务器响应结果:
3、映射操作
有了索引库,等于有了数据库中的database 。
接下来就需要建索引库(index)中的映射了,类似于数据库 (database)中的表结构 (table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射 (mapping)。
1、创建映射
在Postman 中,向 ES 服务器发 PUT 请求http://127.0.0.1:9200/user/_mapping
请求内容为:
{
"properties":{
"name":{
"type": "text",
"index": true
},
"sex":{
"type": "keyword",
"index": true
},
"phone":{
"type": "keyword",
"index": false
}
}
}
服务器的响应
映射数据说明
字段名:任意填写,下面指定许多属性,例如: title 、 subtitle 、 images 、 price
type :类型 Elasticsearch 中支持的数据类型非常丰富,说几个关键的:
基本数据类型:long 、 integer 、 short 、 byte 、 double 、 float 、 half_float
浮点数的高精度类型:scaled_float
text:可分词
keyword:不可分词,数据会作为完整字段进行匹配
String 类型,又分两种:
Numerical :数值类型,分两类
Date :日期类型
Array :数组类型
Object :对象
index :是否索引,默认为 true ,也就是说你不进行任何配置,所有字段都会被索引。
true:字段会被索引,则可以用来进行搜索
false:字段不会被索引,不能用来搜索
store :是否将数据进行独立存储,默认为 false
原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从 _source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从 _source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
analyzer :分词器,这里的 ik_max_word 即使用 ik 分词器
2、查看映射
在Postman 中,向 ES 服务器发 GET 请求http://127.0.0.1:9200/user/_mapping
3、索引映射关联
在Postman 中,向 ES 服务器发 PUT 请求 http://127.0.0.1:9200/user1
3、Java API
1、环境准备
-
创建maven项目
-
导入相关依赖
<dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.8.0</version> </dependency> <!--es的客户端--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> </dependencies>
-
创建测试
public class ElasticSearchTest { public static void main(String[] args) throws IOException { //9200 端口为 Elastic s earch 的 Web 通信端口 localhost 为启动 ES 服务的主机名 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost",9200))); client.close(); } }
没有任何输出或报错信息即是成功
2、索引操作
1、创建索引
ES服务器正常启动后,可以通过 Java API 客户端对象对 ES 索引进行操作
public class ElasticsearchDocCreate {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//创建索引
CreateIndexRequest request = new CreateIndexRequest("user");
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
//创建索引的响应状态
boolean acknowledged = response.isAcknowledged();
System.out.println("响应状态为:" + acknowledged);
client.close();
}
}
输出结果
2、查看索引
public class ElasticsearchDocSearch {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//查询索引
GetIndexRequest request = new GetIndexRequest("user");
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
//查询索引的响应状态
System.out.println(response);
System.out.println(response.getSettings());
System.out.println(response.getAliases());
System.out.println(response.getMappings());
client.close();
}
}
输出结果
3、删除索引
public class ElasticsearchDocDelete {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//删除索引
DeleteIndexRequest request = new DeleteIndexRequest("user");
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
//删除索引的响应状态
System.out.println("删除状态为:" + response.isAcknowledged());
client.close();
}
}
3、文档操作
创建数据模型
public class User {
private String name;
private Integer age;
private String sex;
public User() {
}
public User(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
.add("name='" + name + "'")
.add("age=" + age)
.add("sex='" + sex + "'")
.toString();
}
}
1、创建数据,添加到文档
public class ElasticsearchDocInsert {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
IndexRequest indexRequest = new IndexRequest();
indexRequest.index("user").id("1001");
//创建数据对象
User user = new User("xiaobear",18,"boy");
//数据对象转为JSON
ObjectMapper mapper = new ObjectMapper();
String userJson = mapper.writeValueAsString(user);
indexRequest.source(userJson, XContentType.JSON);
//获取响应对象
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
client.close();
}
}
输出结果
2、修改文档
public class ElasticsearchDocUpdate {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//修改文档
UpdateRequest request = new UpdateRequest();
request.index("user").id("1001");
// 设置请求体,对数据进行修改
request.doc(XContentType.JSON,"sex","girl");
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
client.close();
}
}
输出结果
3、查询文档
public class ElasticsearchDocGet {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//创建请求对象
GetRequest request = new GetRequest().index("user").id("1001");
//创建响应对象
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("source:" + response.getSourceAsString());
client.close();
}
}
输出结果
4、删除文档
public class ElasticsearchDoc_Delete {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200)));
//创建请求对象
DeleteRequest request = new DeleteRequest().index("user").id("1");
//创建响应对象
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
//打印信息
System.out.println(response.toString());
client.close();
}
}
输出结果
5、批量操作
1、批量新增
public class ElasticSearchBatchInsert {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建批量新增请求对象
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON,"name","xiaohuahua"));
request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON,"name","zhangsan"));
request.add(new IndexRequest().index("user").id("1006").source(XContentType.JSON,"name","lisi"));
//创建响应对象
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("took:" + response.getTook());
System.out.println("items:" + response.getItems());
}
}
输出结果
查询文档:
-
http://127.0.0.1:9200/user/_doc/1005
-
http://127.0.0.1:9200/user/_doc/1004
-
http://127.0.0.1:9200/user/_doc/1006
2、批量删除
public class ElasticSearchBatchDelete {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建批量新增请求对象
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));
request.add(new DeleteRequest().index("user").id("1003"));
//创建响应对象
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("took:" + response.getTook());
Arrays.stream(response.getItems()).forEach(System.out::println);
System.out.println("items:" + Arrays.toString(response.getItems()));
System.out.println("status:" + response.status());
System.out.println("失败消息:" + response.buildFailureMessage());
}
}
输出结果
4、高级查询
1、请求体查询
1、查询所有索引数据
public class RequestBodyQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有对象
sourceBuilder.query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
2、term查询
public class TremQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有对象
sourceBuilder.query(QueryBuilders.termQuery("name","zhangsan"));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
3、分页查询
public class PageQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有对象
sourceBuilder.query(QueryBuilders.matchAllQuery());
//分页查询 当前页其实索引 第一条数据的顺序号 from
sourceBuilder.from(0);
//每页显示多少条
sourceBuilder.size(2);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
4、数据排序
public class DataSorting {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有对象
sourceBuilder.query(QueryBuilders.matchAllQuery());
//数据排序
sourceBuilder.sort("age", SortOrder.DESC);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
5、过滤字段
public class FilterFiled {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有对象
sourceBuilder.query(QueryBuilders.matchAllQuery());
//数据排序
sourceBuilder.sort("age", SortOrder.DESC);
//查询过滤字段
String[] excludes = {};
//过滤掉name属性
String[] includes = {"age"};
sourceBuilder.fetchSource(includes,excludes);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
6、Bool查询
public class BoolSearch {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//必须包含
boolQuery.must(QueryBuilders.matchQuery("age",18));
//一定不包含
boolQuery.mustNot(QueryBuilders.matchQuery("name","lisi"));
//可能包含
boolQuery.should(QueryBuilders.matchQuery("name","zhangsan"));
//查询所有对象
sourceBuilder.query(boolQuery);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
7、范围查询
public class RangeSearch {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//范围查询
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
//大于等于
rangeQuery.gte("19");
//小于等于
rangeQuery.lte("40");
//查询所有对象
sourceBuilder.query(rangeQuery);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
8、模糊查询
public class FuzzySearch {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest();
request.indices("user");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//模糊查询
FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("name", "zhangsan");
fuzzyQuery.fuzziness(Fuzziness.ONE);
sourceBuilder.query(fuzzyQuery);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("是否超时:" + response.isTimedOut());
System.out.println("TotalHits:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
}
输出结果
5、高亮查询
public class HighlightQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//高亮查询
SearchRequest request = new SearchRequest("user");
//创建查询请求体构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式,高亮查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");
//设置查询方式
sourceBuilder.query(termQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
//设置标签前缀
highlightBuilder.preTags("<font color='red'");
//设置标签后缀
highlightBuilder.postTags("</font>");
//设置高亮字段
highlightBuilder.field("name");
//设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
//设置请求体
request.source(sourceBuilder);
//客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 打印响应结果
SearchHits hits = response.getHits();
System.out.println("took::"+response.getTook());
System.out.println("time_out::"+response.isTimedOut());
System.out.println("total::"+hits.getTotalHits());
System.out.println("max_s core::"+hits.getMaxScore());
System.out.println("hits::::>>");
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
//打印高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
System.out.println(highlightFields);
System.out.println("<<::::");
}
}
}
输出结果
6、聚合查询
1、最大年龄
public class AggregateQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
SearchRequest request = new SearchRequest().indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
//设置请求体
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//打印响应结果
SearchHits hits = response.getHits();
System.out.println("hits = " + hits);
System.out.println(response);
}
}
输出结果
2、分组查询
public class GroupQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)));
//创建搜索对象
SearchRequest request = new SearchRequest().indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.aggregation(AggregationBuilders.terms("age_groupby").field("age"));
//设置请求体
request.source(searchSourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits());
System.out.println(response);
}
}
输出结果