史上最全Elasticsearch学习

Elasticsearch


一、Elasticsearch简介&安装

1.1、Elasticsearch是什么?

The Elastic Stack, 包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为 ES, ES 是一个开源的高扩展的分布式全文搜索引擎,是整个 Elastic Stack 技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。

1.2、全文搜索引擎

Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。基于以上原因可以分析得出,在一些生产环境中,使用常规的搜索方式,性能是非常差的:

搜索的数据对象是大量的非结构化的文本数据。
文件记录量达到数十万或数百万个甚至更多。
支持大量基于交互式文本的查询。
需求非常灵活的全文搜索查询。
对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。
对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。
为了解决结构化数据搜索和非结构化数据搜索性能问题,我们就需要专业,健壮,强大的全文搜索引擎。这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

1.3、Elasticsearch的应用案例

  • GitHub: 2013 年初,抛弃了 Solr,采取 Elasticsearch 来做 PB 级的搜索。“GitHub 使用Elasticsearch 搜索 20TB 的数据,包括 13 亿文件和 1300 亿行代码”。
  • 维基百科:启动以 Elasticsearch 为基础的核心搜索架构
  • SoundCloud:“SoundCloud 使用 Elasticsearch 为 1.8 亿用户提供即时而精准的音乐搜索服务”。
  • 百度:目前广泛使用 Elasticsearch 作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部 20 多个业务线(包括云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大 100 台机器,200 个 ES 节点,每天导入 30TB+ 数据。
  • 新浪:使用 Elasticsearch 分析处理 32 亿条实时日志。
  • 阿里:使用 Elasticsearch 构建日志采集和分析体系。
  • Stack Overflow:解决 Bug 问题的网站,全英文,编程人员交流的网站。

1.4、Elasticsearch的下载、安装、运行

Download Elasticsearch Free | Get Started Now | Elastic | Elastic

Elasticsearch 的官方地址:https://www.elastic.co/cn/

下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch

Elasticsearch 分为 Linux 和 Windows 版本,未来在企业里肯定是要用linux版本的,并且还要搭建集群。那么这里我学习ES为了方便、快速掌握,就采用windows版本了。

下载完成之后,是一个压缩包,直接解压就可以了。

在这里插入图片描述

  • bin 可执行脚本目录

  • config 配置目录

  • jdk 内置 JDK 目录(ES是采用Java语言开发的)

  • lib 类库

  • logs 日志目录

  • modules 模块目录

  • plugins 插件目录

解压后,进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务。

在这里插入图片描述

注意:9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http 协议的 RESTful 端口。

1.5、有关restful

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。

在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI(Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。

在 REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET、POST、PUT、DELETE,还可能包括 HEAD 和 OPTIONS。简单的理解就是,如果想要访问互联网上的资源,就必须向资源所在的服务器发出请求,请求体中必须包含资源的网络路径,以及对资源进行的操作(增删改查)。


二、Elasticsearch创建/查看/删除索引、创建/查看/修改/删除文档、映射关系

2.1 Elasticsearch中的数据格式

Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,我们将 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比。

在这里插入图片描述

ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个 type,Elasticsearch 7.X 中, Type 的概念已经被删除了。

2.2 索引操作

2.2.1 创建索引

在ES中创建一个索引,就相当于在mysql中创建了一个数据库,而mysql中的数据库肯定是不能重复的,也即ES中的索引也不能重复,所以这是一个幂等性操作,需要发送PUT请求(如果重复发送PUT请求、重复添加索引,会返回错误信息),这里不能发送POST请求。

在这里插入图片描述

2.2.2 查看指定索引

在postman中,向ES服务器发送GET请求。这里的路径和上边的创建索引是一样的,只是请求方式不一样

在这里插入图片描述

2.2.3 查看全部索引

在 Postman 中,向 ES 服务器发 GET 请求。

  • health 当前服务器健康状态:green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
  • status 索引打开、关闭状态
  • index 索引名
  • uuid 索引统一编号
  • pri 主分片数量
  • rep 副本数量
  • docs.count 可用文档数量
  • docs.deleted 文档删除状态(逻辑删除)
  • store.size 主分片和副分片整体占空间大小
  • pri.store.size 主分片占空间大小

在这里插入图片描述

2.2.4 删除索引

在 Postman 中,向 ES 服务器发 DELETE 请求。

在这里插入图片描述

2.3 文档操作

2.3.1 创建文档

索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式

在 Postman 中,向 ES 服务器发 POST 请求。

{
	"title":"小米手机",
	"category":"小米",
	"image":"http://www.szh.com/szh.jpg",
	"price":3999.00
}

在这里插入图片描述

上面的数据创建后,由于没有指定数据唯一性标识(ID),默认情况下,ES 服务器会随机生成一个。

如果想要自定义唯一性标识,需要在创建时指定。推荐使用下面这种方式创建文档。

在这里插入图片描述

2.3.2 查看单个文档:主键查询

查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询。在 Postman 中,向 ES 服务器发 GET 请求。

在这里插入图片描述

2.3.3 查看所有文档:全查询

“query”:这里的query代表一个查询对象,里面可以有不同的查询属性

“match_all”:查询类型,例如:match_all(代表查询所有),match,term,range等等

{查询条件}:查询条件会根据类型的不同,写法也有差异

在这里插入图片描述

2.3.4 修改文档中的全部字段

修改数据时,也可以只修改某一给条数据的局部信息,也可以修改所有字段信息。

修完完之后,再次发送GET请求,查看修改后的文档内容。

{
   "title":"OPPO手机",
   "category":"OPPO",
   "images":"http://www.szh.com/szh.jpg",
   "price":2400.00
}

在这里插入图片描述

在这里插入图片描述

2.3.5 修改文档中的某个字段
{
   "doc" : {
       "title":"VIVO手机",
       "category":"VIVO"
   }
}

在这里插入图片描述

在这里插入图片描述

2.3.6 删除文档

删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。在 Postman 中,向 ES 服务器发 DELETE 请求。

在这里插入图片描述

2.3.7 条件查询文档内容

match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系。

在 Postman 中,向 ES 服务器发 GET 请求。

在这里插入图片描述

上面这种查询方式的请求参数是直接跟在请求路径之后的,这种方式不太好,因为可能会造成乱码问题。

所以一般采用下面这种方式,将请求参数存放在请求体中。

{
   "query" : {
       "match" : {
           "category" : "华为"
       }
   }
}

在这里插入图片描述

2.3.8 分页查询+排序文档内容

默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source 的过滤

sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc 升序。

from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size。

size:每页显示多少条。

{
   "query" : {
       "match_all" : {

       }
   },
   "from" : 0, // (页码-1)*每页条数, 第一页:(1-1)*2=0, 第二页:(2-1)*2=2
   "size" : 2,
   "_source" : ["title","price"],
   "sort" : {
       "price" : {
           "order" : "desc"
       }
   }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.9 多条件查询:and

bool把各种其它查询通过must(必须 and )、must_not(必须不)、should(应该 or)的方式进行组合 。

{
	"query" : {
		"bool" : {
			"must" : [
				{
					"match" : {
						"category" : "小米"
					}
				},
				{
					"match" : {
						"price" : 3999.00
					}
				}
			]
		}
	}
}

在这里插入图片描述

2.3.10 多条件查询:or

bool把各种其它查询通过must(必须 and )、must_not(必须不)、should(应该 or)的方式进行组合 。

{
	"query" : {
		"bool" : {
			"should" : [
				{
					"match" : {
						"category" : "VIVO"
					}
				},
				{
					"match" : {
						"price" : 5999.00
					}
				}
			]
		}
	}
}

在这里插入图片描述

2.3.11 多条件查询:大于、小于

range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符:
gt 大于> gte 大于等于>= lt 小于< lte 小于等于<=

{
	"query" : {
		"bool" : {
			"must" : [
				{
					"match" : {
						"category" : "小米"
					}
				}
			],
			"filter" : {
				"range" : {
					"price" : {
						"gt" : 3000.00,
                       "lt" : 4000.00
					}
				}
			}
		}
	}
}

在这里插入图片描述

2.3.12 全文查询+高亮显示

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。

在使用 match 查询的同时,加上一个 highlight 属性:

  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
  • title:这里声明 title 字段需要高亮,后面可以为这个字段设置特有配置,也可以空
{
   "query" : {
       "match_phrase" : {
           "category" : "小"
       }
   },
   "highlight" : {
       "fields" : {
           "category" : {}
       }
   }
}

在这里插入图片描述

当我们将查询条件中的 match_phrase 改为 match 之后,再次查询,结果仍然是有的。这就很奇怪了,我文档中分类信息只有 小米 、没有 小 啊,为什么还能查询到结果呢? 这是因为ES在保存文档数据时,会将数据进行分词、拆解操作,并将拆解后的数据保存到倒排索引中,这样即使使用文字的一部分(小米可以查询到、小也可以查询到)也能查询到数据,这种方式就称为 全文检索。 也就是说文档中的category是小米,

通过 小、米、小米 均可以查询到。

如果我们写的是 小华,则ES会帮我们查询出:%小%、%华% 相关的所有数据,这里就是进行了数据分词、拆解,进而采用倒排索引的方式查询。

假如说,我不想采用采用这种全文检索的匹配模式,需要将 match 改为 match_phrase。

在这里插入图片描述

2.3.13 聚合查询:根据价格分组、对价格求平均值

聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值、平均值等等。

  • 对某个字段取最大值 max
  • 对某个字段取最小值 min
  • 对某个字段求和 sum
  • 对某个字段取平均值 avg
  • 对某个字段的值进行去重之后再取总数 distinct
{
   "aggs" : { //聚合操作
       "price_group" : { //名称,自定义
           "terms" : { //分组
               "field" : "price" //分组字段
           }
       }
   },
   "size" : 0
}

在这里插入图片描述

{
   "aggs" : { //聚合操作
       "price_avg" : { //名称,自定义
           "avg" : { //分组
               "field" : "price" //分组字段
           }
       }
   },
   "size" : 0
}

在这里插入图片描述

2.4 映射操作

有了索引库,等于有了数据库中的 database。

接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。

  • 字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price

  • type:类型,Elasticsearch 中支持的数据类型非常丰富,说几个关键的:
    ​ String 类型,又分两种:
    ​ text:可分词

​ keyword:不可分词,数据会作为完整字段进行匹配
​ Numerical:数值类型,分两类
​ 基本数据类型:long、integer、short、byte、double、float、half_float
​ 浮点数的高精度类型:scaled_float
​ Date:日期类型
​ Array:数组类型
​ Object:对象

  • index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。
    ​ true:字段会被索引,则可以用来进行搜索
    ​ false:字段不会被索引,不能用来搜索

  • store:是否将数据进行独立存储,默认为 false
    ​ 原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置

  • analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器

首先是 http://127.0.0.1:9200/user ,发送PUT请求,创建一个user索引,然后在这个索引下创建一个映射。

就类似于在mysql中创建一个名为 user 的数据库,在这个数据库中定义一张表的结构如下:👇👇👇

text 类型为true表示 name 字段可以支持 分词、拆解 操作的查询;而 keyword 类型为true表示 sex 字段仅支持完全匹配的模式;最后 keyword 类型为false表示 tel 字段不支持查询。

{
	"properties" : {
		"name" : {
			"type" : "text",
			"index" : true
		},
		"sex" : {
			"type" : "keyword",
			"index" : true
		},
		"tel" : {
			"type" : "keyword",
			"index" : false
		}
	}
}

在这里插入图片描述

索引有了,映射也有了(数据库有了,表结构有了,就差向表中添加数据了),也就是需要添加文档内容。

在这里插入图片描述

因为name字段是支持text模式查询,即支持分词、拆解操作,做倒排索引,所以虽然文档中的name字段为张起灵,但是经过分词拆解,name为徐、凤、年、凤年 这几种都可以查询出数据。

在这里插入图片描述

由于 sex 字段不支持text分词拆解,仅支持keyword完全匹配的模式,所以源文档数据中 sex 为 man,这里只写个 m 是查询不到的。

在这里插入图片描述

最后的tel字段是最苛刻的,压根不支持text、keyword两种查询,所以这里就算是写成和文档中的 tel 一样,也查询不到,因为 tel 字段不支持查询。

在这里插入图片描述


三、Elasticsearch——使用Java API实现ES中的索引、映射、文档操作

3.1 简单介绍

之前是对ES中的创建/查看/删除索引、创建定义映射、创建/查看/修改/删除文档的这些操作有了一定的了解认识,但是是通过Postman + JSON串的方法来实现的

那么之后仍然是对ES中的索引、映射、文档进行操作,只是方法换成了Java API。

3.2 案例详情

首先需要创建一个maven工程,必然要添加ES相关的依赖。

同时双击ES安装目录的bin目录下的 elasticsearch.bat ,先启动ES服务端。

pom文件

       <dependency>
           <groupId>org.elasticsearch</groupId>
           <artifactId>elasticsearch</artifactId>
           <version>7.8.0</version>
       </dependency>
       <!-- elasticsearch 的客户端 -->
       <dependency>
           <groupId>org.elasticsearch.client</groupId>
           <artifactId>elasticsearch-rest-high-level-client</artifactId>
           <version>7.8.0</version>
       </dependency>
       <!-- elasticsearch 依赖 2.x 的 log4j -->
       <dependency>
           <groupId>org.apache.logging.log4j</groupId>
           <artifactId>log4j-api</artifactId>
           <version>2.8.2</version>
       </dependency>
       <dependency>
           <groupId>org.apache.logging.log4j</groupId>
           <artifactId>log4j-core</artifactId>
           <version>2.8.2</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.9.9</version>
       </dependency>
       <!-- junit 单元测试 -->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
       </dependency>
3.2.1 创建ES客户端:完成与ES服务端连接

后边都是按照这个模板代码来的

package com.szh.es;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;

import java.io.IOException;

/**
*
*/
public class ESTestClient {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //关闭ES客户端
       esClient.close();
   }
}
3.2.2 创建索引
//创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //创建索引 --- 请求对象
       CreateIndexRequest request = new CreateIndexRequest("user");
       //发送请求 --- 获取响应
       CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);

       //响应状态
       boolean acknowledged = response.isAcknowledged();
       System.out.println("索引操作:" + acknowledged);

       //关闭ES客户端
       esClient.close();

3.2.3 查看索引

public class ESTestIndexSearch {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //查询索引 --- 请求对象
       GetIndexRequest request = new GetIndexRequest("user");
       //发送请求 --- 获取响应
       GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT);

       //响应状态
       System.out.println(response.getAliases());
       System.out.println(response.getMappings());
       System.out.println(response.getSettings());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.4 删除索引

public class ESTestIndexDelete {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //删除索引 --- 请求对象
       DeleteIndexRequest request = new DeleteIndexRequest("user");
       //发送请求 --- 获取响应
       AcknowledgedResponse response = esClient.indices().delete(request,RequestOptions.DEFAULT);

       //响应状态
       System.out.println(response.isAcknowledged());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.5 创建文档

索引有了,就相当于有了数据库。接下来就需要向数据库中建表、添加数据。建表自然要有表结构(有哪些属性、这些属性分别都是什么数据类型),也就是ES中的映射,在Java代码中就可以采用实体类来实现。


public class User {

   private String name;
   private String sex;
   private Integer age;

   //getter and setter
}

public class ESTestDocInsert {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //创建文档 --- 请求对象
       IndexRequest request = new IndexRequest();
       //设置索引及索引中文档的唯一性标识id(如果不指定,则ES会默认随机生成一个id)
       request.index("user").id("1001");

       //创建数据对象(文档内容)
       User user = new User();
       user.setName("张起灵");
       user.setSex("man");
       user.setAge(21);

       //向ES中插入数据,必须将数据格式转换为JSON
       ObjectMapper objectMapper = new ObjectMapper();
       String userJson = objectMapper.writeValueAsString(user);
       request.source(userJson, XContentType.JSON);

       //发送请求 --- 获取响应
       IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
       System.out.println(response.getResult());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.6 修改文档

public class ESTestDocUpdate {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //修改文档 --- 请求对象
       UpdateRequest request = new UpdateRequest();
       //配置修改参数 --- 表示要修改user索引中id为1001的文档内容
       request.index("user").id("1001");
       //将修改后的内容,以JSON格式写入请求体中
       request.doc(XContentType.JSON,"age",18);

       //发送请求 --- 获取响应
       UpdateResponse response = esClient.update(request,RequestOptions.DEFAULT);
       System.out.println(response.getResult());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.7 查看文档

public class ESTestDocSearch {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //查询文档 --- 请求对象
       GetRequest request = new GetRequest();
       //设置请求参数 --- 表示要查询user索引中id为1001的文档内容
       request.index("user").id("1001");

       //发送请求 --- 获取响应
       GetResponse response = esClient.get(request,RequestOptions.DEFAULT);
       System.out.println(response.getSourceAsString());

       //关闭ES客户端
       esClient.close();
   }
}

3.2.8 删除文档
public class ESTestDocDelete {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //删除文档 --- 请求对象
       DeleteRequest request = new DeleteRequest();
       //设置请求参数 --- 表示要删除user索引中id为1001的文档
       request.index("user").id("1001");
       
       //发送请求 --- 获取响应
       DeleteResponse response = esClient.delete(request,RequestOptions.DEFAULT);
       System.out.println(response.getResult());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.9 批量创建文档

public class ESTestDocInsertBatch {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //批量新增文档 --- 请求对象
       BulkRequest request = new BulkRequest();
       //以JSON格式批量新增文档 --- 存入请求体中
       request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张起灵","sex","boy","age",21));
       request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "小哥","sex","boy","age",18));
       request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "小宋","sex","boy","age",20));

       //发送请求 --- 获取响应
       BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
       System.out.println(response.getTook());

       //关闭ES客户端
       esClient.close();
   }
}
3.2.10 批量删除文档

public class ESTestDocDeleteBatch {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //批量删除文档 --- 请求对象
       BulkRequest request = new BulkRequest();
       //将要删除的文档id存入请求体中
       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 = esClient.bulk(request,RequestOptions.DEFAULT);
       System.out.println(response.getTook());
       System.out.println(response.getItems());

       //关闭ES客户端
       esClient.close();
   }
}

3.2.11 全量查询

因为上面两个代码案例分别进行了批量创建、批量删除。所以这里首先执行一次批量创建的代码,确保索引中有多条数据供我们查询。


public class ESTestDocInsertBatch {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //批量新增文档 --- 请求对象
       BulkRequest request = new BulkRequest();
       //以JSON格式批量新增文档 --- 存入请求体中
       request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张起灵","sex","boy","age",21));
       request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "小哥","sex","boy","age",18));
       request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "小宋","sex","boy","age",20));
       request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "冷少","sex","boy","age",25));
       request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "Java软件工程师","sex","girl","age",40));

       //发送请求 --- 获取响应
       BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
       System.out.println(response.getTook());

       //关闭ES客户端
       esClient.close();
   }
}

下面首先进行全量查询操作。


public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //1.查询索引中的全部文档 --- matchAllQuery 全量查询
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体 --- 存入搜索请求对象中
       request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

3.2.12 条件查询

做匹配查询,查询年龄age=21的文档内容。

public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //2.条件查询--- termQuery age=21
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体 --- 存入搜索请求对象中
       request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age",21)));

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

3.2.13 分页查询

做全量查询,对查询结果进行分页显示,每页2条数据,查询第1页。

查看第几页:(页码 - 1)*每页条数

public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //3.分页查询
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体
       SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
       builder.from(0);
       builder.size(2);
       //将构建好的查询请求体存入搜索请求对象中
       request.source(builder);

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

3.2.14 排序查询

做全量查询,对查询结果中的年龄age字段做降序排序。

public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //4.对查询结果进行排序
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体
       SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
       builder.sort("age", SortOrder.DESC);
       //将构建好的查询请求体存入搜索请求对象中
       request.source(builder);

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

3.2.15 过滤字段查询

做全量查询,同时排除性别sex字段。


public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //5.过滤字段
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体
       SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
       String[] excludes = {"sex"};
       String[] includes = {};
       builder.fetchSource(includes,excludes);
       //将构建好的查询请求体存入搜索请求对象中
       request.source(builder);

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

3.2.16 组合条件查询

查询年龄 age=18 或者 name=张起灵 的文档内容。


public class ESTestDocQuery {
   public static void main(String[] args) throws IOException {
       //创建ES客户端
       RestHighLevelClient esClient = new RestHighLevelClient(
               RestClient.builder(new HttpHost("localhost",9200,"http"))
       );

       //6.组合查询
       //创建搜索请求对象
       SearchRequest request = new SearchRequest();
       //设置参数 --- 表示查询哪个索引中的文档内容
       request.indices("user");
       //构建查询的请求体
       SearchSourceBuilder builder = new SearchSourceBuilder();
       BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
       boolQueryBuilder.should(QueryBuilders.matchQuery("age",18));
       boolQueryBuilder.should(QueryBuilders.matchQuery("name","张起灵"));
       builder.query(boolQueryBuilder);
       //将构建好的查询请求体存入搜索请求对象中
       request.source(builder);

       //发送请求 --- 获取响应
       SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
       //获取查询到的结果集
       SearchHits hits = response.getHits();
       System.out.println(hits.getTotalHits()); //结果集的条数
       System.out.println(response.getTook());  //总耗时
       //遍历结果集
       for (SearchHit hit : hits) {
           System.out.println(hit.getSourceAsString());
       }

       //关闭ES客户端
       esClient.close();
   }
}

    RestClient.builder(new HttpHost("localhost",9200,"http"))
   );

   //6.组合查询
   //创建搜索请求对象
   SearchRequest request = new SearchRequest();
   //设置参数 --- 表示查询哪个索引中的文档内容
   request.indices("user");
   //构建查询的请求体
   SearchSourceBuilder builder = new SearchSourceBuilder();
   BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
   boolQueryBuilder.should(QueryBuilders.matchQuery("age",18));
   boolQueryBuilder.should(QueryBuilders.matchQuery("name","张起灵"));
   builder.query(boolQueryBuilder);
   //将构建好的查询请求体存入搜索请求对象中
   request.source(builder);

   //发送请求 --- 获取响应
   SearchResponse response = esClient.search(request,RequestOptions.DEFAULT);
   //获取查询到的结果集
   SearchHits hits = response.getHits();
   System.out.println(hits.getTotalHits()); //结果集的条数
   System.out.println(response.getTook());  //总耗时
   //遍历结果集
   for (SearchHit hit : hits) {
       System.out.println(hit.getSourceAsString());
   }

   //关闭ES客户端
   esClient.close();

}
}



  • 12
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值