Elastic Search
简介Elasticsearch是一个开源的,高扩展、分布式、RESTful 风格的搜索和数据分析引擎,是整个 Elastic Stack 技术栈的核心。Elasticsearch是一个基于Apache Lucene™的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。Elasticsearch本身扩展性很好,可以在你的笔记本上运行,也可
简介
Elasticsearch是一个开源的,高扩展、分布式、RESTful 风格的搜索和数据分析引擎,是整个 Elastic Stack 技术栈的核心。
Elasticsearch是一个基于Apache Lucene™的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
Elasticsearch本身扩展性很好,可以在你的笔记本上运行,也可以在数以百计的服务器上处理PB级别的数据。
可以近乎实时的存储、检索数据。用于全文搜索、结构化搜索、分析以及将这三者混合使用。
Elasticsearch使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,通过简单的 RESTful API 来降低Lucene的复杂性,让全文搜索变得简单。
全文搜索
全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
结构化数据&非结构化数据
信息基本可以划分为两大类。一类信息能够用数据或统一的结构可以表示,称之为结构化数据,如数字、符号;而另一类信息无法用数字或统一的结构表示,如文本、图像、声音、网页等,称之为非结构化数据。结构化数据属于非结构化数据,是非结构化数据的特例。
结构化数据
结构化数据也称为行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。
一句话:指具有固定格式或有限长度的数据
对于结构化数据,一般可以通过关系型数据库表方式存储和搜索,也可以建立索引
非结构化数据
非结构化数据是数据结构不规则或不完整,没有预定义的数据模型,不方便用数据库二维逻辑表来表现的数据。非结构化数据其格式非常多样,标准也是多样性的,其字段长度可变,并且每个字段的记录又可以由可重复或不可重复的子字段构成的数据库,用它不仅可以处理结构化数据(如数字、符号等信息)而且更适合处理非结构化数据(全文文本、图象、声音、影视、超媒体等信息)。
一句话:指不定长或无固定格式的数据
对于非结构化数据,全文数据的搜索主要有两种方法:顺序扫描法,全文检索。
顺序扫描法
顾名思义,按照顺序扫描的方式查询特定的关键字
全文检索
将非结构化数据中的一部分信息提取出来,重新组织,让其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的,这提取出的然后重新组织的信息,称之索引。
数据清洗
随着网络技术的发展使得数据的数量日趋增大,从多个业务系统中抽取而来而且包含历史数据,这样就避免不了数据错误、不完整、重复,相互冲突等,这些错误的或有冲突的数据显然是我们不想要的,称为“脏数据”。我们要按照一定的规则把“脏数据”“洗掉”,这就是数据清洗。
Solr&Lucene
Solr
Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。
Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
它是一个成熟的产品,拥有强大而广泛的用户社区。它提供分布式索引,复制,负载平衡查询以及自动故障转移和恢复。
Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中。它对外提供类似于Web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式的文件生成索引,也可以通过提出查找请求并得到返回结果。
目前市面上流行的搜索引擎软件,主流的就两款:Elasticsearch 和 Solr,这两款都是基 于 Lucene 搭建的,可以独立部署启动的搜索引擎服务软件。
Lucene
Lucene 都是是 Apache 软件基金会 Jakarta 项目组的一个子项目,是一个开放源代码的全文检索引擎工具包。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。
Elasticsearch&Solr比较
• 两个搜索引擎都是流行的,先进的的开源搜索引擎。
• 底层搜索库 - Lucene构建的。
• 与Solr相比,Elasticsearch易于安装非常轻巧。
• Solr拥有更大,更成熟的用户,开发者和贡献者社区。Solr是真正的开源社区代码,任何人都可以为Solr做出贡献。
• Solr贡献者和提交者来自许多不同的组织,而Elasticsearch提交者来自单个公司。
• 单纯的对已有数据进行搜索时,Solr更快。
• 当实时建立索引时,Solr会产生io阻塞,查询性能较差,Elasticsearch具有明显的优势。
• 随着数据量的增加,Solr的搜索效率会变得更低,而Elasticsearch却没有明显的变化。
特征差异:
RESTful
下载与安装(win版7.8.0为例)
官方地址:https://www.elastic.co/cn/
下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
解压即安装
进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务。
9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http 协议 RESTful 端口
浏览器访问:http://localhost:9200,看到返回结果即访问成功
ES数据格式
Elasticsearch 是面向文档型数据库。ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。 这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个 type,Elasticsearch 7.X 中, Type 的概念已经被删除了。
与MySql类比
倒排索引
倒排索引(Inverted Index)也叫反向索引,有反向索引就有正向索引。通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key。
倒排索引记录每个词条出现在哪些文档,及文档中的位置,可以根据词条快速定位到包含这个词条的文档及出现的位置。
一段文本经过分析器分析以后就会输出一串单词,这一个一个的就叫做Term。单词字典(Term Dictionary)可以理解为Term的集合。为了更快的找到某个单词,建立单词索引(Term Index)。倒排列表(Posting List)记录了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。
举个例子:
每个文档都有一个ID,如果插入的时候没有指定的话,Elasticsearch会自动生成一个
Elasticsearch分别为每个字段都建立了一个倒排索引。比如,在上面“熊一”,“森林”这些都是Term,而[1,2]就是Posting List。Posting list就是一个数组,存储了所有符合某个Term的文档ID。只要知道文档ID,就能快速找到文档。在倒排索引中,为Terms建立索引,通过Term索引可以找到Term在Term Dictionary中的位置,进而找到Posting List,有了倒排列表就可以根据ID找到文档了。
HTTP 操作
索引
创建
对比关系型数据库,创建索引就等同于创建数据库。
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/fruits
服务器返回响应如下:
{
"acknowledged": true, //【响应结果】
"shards_acknowledged": true, //【分片结果】
"index": "fruits" //【索引名称】
}
创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片
如果重复添加索引,会返回错误信息如下:
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [fruits/4xU9qTnUQlm_pIMOCtEBVQ] already exists", 【已存在】
"index_uuid": "4xU9qTnUQlm_pIMOCtEBVQ",
"index": "fruits"
}
],
"type": "resource_already_exists_exception",
"reason": "index [fruits/4xU9qTnUQlm_pIMOCtEBVQ] already exists",
"index_uuid": "4xU9qTnUQlm_pIMOCtEBVQ",
"index": "fruits"
},
"status": 400
}
查看单个索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/fruits
服务器响应结果如下:
{
"fruits": { //【索引名】
"aliases": {}, //【别名】
"mappings": {}, //【映射】
"settings": { //【设置】
"index": { //【设置-索引】
"creation_date": "1618124097675", //【设置-索引-创建时间】
"number_of_shards": "1", //【设置-索引-主分片数量】
"number_of_replicas": "1", //【设置-索引-副分片数量】
"uuid": "4xU9qTnUQlm_pIMOCtEBVQ", //【设置-索引-唯一标识】
"version": { //【设置-索引-版本】
"created": "7080099"
},
"provided_name": "fruits" //【设置-索引-名称】
}
}
}
}
查看所有索引
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open fruits 4xU9qTnUQlm_pIMOCtEBVQ 1 1 0 0 208b 208b
yellow open fruits2 ZqHHQ8pMSoCjYK4KCfkfmA 1 1 0 0 208b 208b
删除索引
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/fruits
服务器返回响应如下:
{
"acknowledged": true
}
文档操作
创建文档
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/fruits/_doc
请求体内容为:
{
"title":"苹果",
"des":"甜,大口的吃",
"price":8
}
服务器返回响应如下:
{
"_index": "fruits", //【索引】
"_type": "_doc", //【类型-文档】
"_id": "3Rrbv3gBuh9NI43DIp6U", //【唯一标识】
"_version": 1, //【版本】
"result": "created", //【结果】
"_shards": { //【分片】
"total": 2, //【分片总数】
"successful": 1, //【分片 - 成功】
"failed": 0 //【分片 - 失败】
},
"_seq_no": 0,
"_primary_term": 1
}
查看文档
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/fruits/_search
服务器返回响应如下:
"hits": [
{
"_index": "fruits",
"_type": "_doc",
"_id": "5RoDwHgBuh9NI43D156u",
"_score": 1.0,
"_source": {
"title": "苹果",
"des": "甜,大口的吃",
"price": 8
}
}
]
指定文档的唯一性标识
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/fruits/_doc/1
服务器返回响应如下:
{
"_index": "fruits",
"_type": "_doc",
"_id": "1", //<---------------------id变成1了
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
查询
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/fruits/_doc/1,即可返回结果。
修改文档
修改请求体内容:
{
"title":"榴莲",
"des":"甜,大口的吃",
"price":100
}
在 Postman 中,向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/fruits/_doc/1
{
"_index": "fruits",
"_type": "_doc",
"_id": "1",
"_version": 2, // <---------------- 版本变为2
"result": "updated", //<-------------updated成功
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
修改字段
修改请求体内容:
{
"doc": {
"title":"炮弹"
}
}
在 Postman 中,向 ES 服务器发 POST 请求:http://127.0.0.1:9200/fruits/_update/1 修改数据
在 Postman 中,向 ES 服务器发 GET请求:http://127.0.0.1:9200/fruits/_doc/1 查看已改数据
删除文档
在 Postman 中,向 ES 服务器发 DELETE 请求 :http://127.0.0.1:9200/fruits/_doc/1
按条件删除
请求体内容为:
{
"query":{
"match":{
"title": "炮弹"
}
}
}
向 ES 服务器发 POST 请求 :http://127.0.0.1:9200/fruits/_delete_by_query
服务器返回响应如下:
{
"took": 37, //【耗时】
"timed_out": false, //【是否超时】
"total": 1, //【总数】
"deleted": 1, //【删除数量】
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1.0,
"throttled_until_millis": 0,
"failures": []
}
查询
条件查询
在 Postman 中,向 ES 服务器发 GET请求:http://127.0.0.1:9200/fruits/_search?q=category=苹果
服务器返回响应如下:
{
"took": 9, //【查询花费时间,单位毫秒】
"timed_out": false, //【是否超时】
"_shards": { //【分片信息】
"total": 1, //【总数】
"successful": 1, //【成功】
"skipped": 0, //【忽略】
"failed": 0 //【失败】
},
"hits": { //【搜索命中结果】
"total": { //【搜索条件匹配的文档总数】
"value": 1, //【总命中计数的值】
"relation": "eq" //【计数规则 eq 表示计数准确, gte 表示计数不准确】
},
"max_score": 0.5753642, //【匹配度分值】
"hits": [ //【命中结果集合】
{
"_index": "fruits",
"_type": "_doc",
"_id": "1",
"_score": 0.5753642,
"_source": {
"title": "苹果",
"des": "甜,大口的吃",
"price": 8
}
}
]
}
}
匹配查询
match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系 。
请求体内容为:
{
"query":{
"match":{
"title":"苹果"
}
}
}
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/fruits/_search
全量查询
请求体内容为:
{
"query":{
"match_all":{
}
}
}
分页查询
from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size size:每页显示多少条 在 Postman 中
请求体内容为:
{
"query": {
"match_all": {}
},
"from": 0,
"size": 2
}
排序
sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc 升序。
请求体内容为:
{
"query": {
"match_all": {}
},
"sort": [{
"price": {
"order":"desc"
}
}]
}
多条件查询
请求体内容为:
{
"query":{
"bool":{
"must":[ //<----------------------------must类似and,should类似or
{
"match":{
"title":"鸭梨"
}
},
{
"match":{
"price":8
}
}
],
"filter":{
"range":{ //<-----------------范围条件
"price":{
"gt": 4
}
}
}
}
}
}
范围查询
range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符
• gt 大于>
• gte 大于等于>=
• lt 小于<
• lte 小于等于<=
高亮
{
"query":{
"match":{
"title":"梨"
}
},
"highlight":{
"fields":{
"title":{}
}
}
}
聚合
{
"aggs":{ //聚合操作
"price_group":{ // 名称,随意
"terms":{ // 分组 最大值max,最小值min,求和sum,平均avg,state 聚合
"field":"price" // 分组字段
}
}
},
"size":0 //对某个字段的值进行去重之后再取总数
}
在这里插入代码片
映射
映射类似于数据库中的表结构。 创建数据库表需要设置字段名称,类型,长度等,索引库也一样,知道这个类型 下有哪些字段,每个字段有哪些约束信息,这就叫做映射。
请求体内容为:
{
"properties": {
"name":{
"type": "text",
"index": true
},
"age":{
"type": "long",
"index": false
}
}
}
在 Postman 中,向 ES 服务器发 PUT 请求 :http://127.0.0.1:9200/person/_mapping
字段名:任意填写
type:类型。常见的有:
- String 类型,又分两种
- text:可分词
- keyword:不可分词,数据会作为完整字段进行匹配
- Numerical:数值类型,分两类
- 基本数据类型:long、integer、short、byte、double、float、half_float
- 浮点数的高精度类型:scaled_float
- Date:日期类型
- Array:数组类型
- Object:对象
- index:是否索引,默认为true。true:会被索引,可以用来进行搜索,false:不会被索引,不能用来搜索
- store:是否将数据进行独立存储,默认为 false 。默认情况下会存储在_source里面,独立存储某个字段只要设置 true 即可,独立存储要比从_source 中解析快,但是也会占用更多的空间,根据实际业务需求来设置。
- analyzer:分词器
Java API
<!-- server -->
<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>
索引
创建
try {
// 创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 创建索引
CreateIndexRequest request = new CreateIndexRequest("person");
CreateIndexResponse createIndexResponse = esClient.indices().create(request, RequestOptions.DEFAULT);
// 响应状态
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("操作状态 = " + acknowledged);
// 关闭连接
esClient.close();
} catch (IOException e) {
e.printStackTrace();
}
查看
// 创建ES客户端
// 查询索引
GetIndexRequest request = new GetIndexRequest("person");
GetIndexResponse getIndexResponse = esClient.indices().get(request, RequestOptions.DEFAULT);
System.out.println(getIndexResponse);
// 关闭连接
删除
// 创建ES客户端
// 删除索引
DeleteIndexRequest request = new DeleteIndexRequest("person");
AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
// 关闭连接
文档
person实体类
public class Person {
private String name;
private String sex;
private Integer age;
// set get方法
}
新增
// 创建ES客户端
// 插入数据
// 请求对象
IndexRequest request = new IndexRequest();
// 设置索引及唯一性标识
request.index("person").id("001");
// 创建数据对象
Person person = new Person();
person.setName("阿强");
person.setAge(86);
person.setSex("女");
// 添加文档数据,JSON 格式
ObjectMapper mapper = new ObjectMapper();
String value = mapper.writeValueAsString(person);
request.source(value, XContentType.JSON);
// 客户端发送请求,获取响应对象
IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
System.out.println(response);
// 关闭连接
新增多个
// 创建ES客户端
// 多个数据
BulkRequest request = new BulkRequest().add(new IndexRequest().index("person").id("001").
source(XContentType.JSON, "name", "小熊熊", "age", "10"),
new IndexRequest().index("person").id("002").
source(XContentType.JSON, "name", "小光光", "age", "22"));
BulkResponse responses = esClient.bulk(request, RequestOptions.DEFAULT);
System.out.println(responses);
// 关闭连接
修改
// 创建ES客户端
// 修改数据
UpdateRequest request = new UpdateRequest();
request.index("person").id("001");
request.doc(XContentType.JSON, "sex", "男");
UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
System.out.println(response);
// 关闭连接
查询
// 创建ES客户端
// 查询数据
GetResponse response = esClient.get(new GetRequest().index("person").id("001"),RequestOptions.DEFAULT);
System.out.println(response.getSourceAsString());
// 关闭连接
全量查询
// 创建ES客户端
// 全量查询
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// 创建搜索请求对象
SearchRequest request = new SearchRequest().indices("person").source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
// 获取数据
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
// 关闭连接
条件查询
// 创建ES客户端
//条件查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("age",10));
// 创建搜索请求对象
// 获取数据
// 关闭连接
分页查询
// 创建ES客户端
// 分页查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).from(0).size(1);
// 创建搜索请求对象
// 获取数据
// 关闭连接
排序
// 创建ES客户端
// 排序
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("age", SortOrder.DESC);
// 创建搜索请求对象
// 获取数据
// 关闭连接
过滤字段
// 创建ES客户端
// 过滤字段
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).fetchSource("name","age");
// 创建搜索请求对象
// 获取数据
// 关闭连接
组合查询
// 创建ES客户端
// 组合查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// boolQueryBuilder.must(QueryBuilders.matchQuery("age", 22));
// boolQueryBuilder.must(QueryBuilders.matchQuery("name", "小光光"));
boolQueryBuilder.should(QueryBuilders.matchQuery("name", "小光光"));
boolQueryBuilder.should(QueryBuilders.matchQuery("age", 10));
sourceBuilder.query(boolQueryBuilder);
// 创建搜索请求对象
// 获取数据
// 关闭连接
范围查询
// 创建ES客户端
// 范围查询
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
// 大于等于
rangeQuery.gt("11");
// 小于等于
// rangeQuery.lte("50");
// 创建搜索请求对象
// 获取数据
// 关闭连接
模糊查询
// 创建ES客户端
// 模糊查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(
QueryBuilders.fuzzyQuery("name", "熊熊").fuzziness(Fuzziness.ONE)
);
// 创建搜索请求对象
// 获取数据
// 关闭连接
高亮查询
// 创建ES客户端
//高亮
// 创建查询请求体构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式:高亮查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "小熊熊");
//设置查询方式
sourceBuilder.query(termQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color = 'pink'>");
highlightBuilder.postTags("</font>");
highlightBuilder.field("name");
sourceBuilder.highlighter(highlightBuilder);
// 创建搜索请求对象
// 获取数据
// 关闭连接
聚合查询
// 创建ES客户端
// 聚合查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().aggregation(
AggregationBuilders.max("maxAge").field("age")
);
// 创建搜索请求对象
// 获取数据
// 关闭连接
删除
// 创建ES客户端
// 删除数据
DeleteResponse response = esClient.delete(new DeleteRequest().index("person").id("001"), RequestOptions.DEFAULT);
System.out.println(response.toString());
// 关闭连接
删除多个
// 创建ES客户端
// 多个数据
BulkRequest request = new BulkRequest().add(new DeleteRequest().index("person").id("001"),
new DeleteRequest().index("person").id("002"),new DeleteRequest().index("person").id("004"));
BulkResponse responses = esClient.bulk(request, RequestOptions.DEFAULT);
System.out.println(responses);
// 关闭连接
集群
博主已堕落。。。。。。
。
。
。
有时间在更。。。。。。
I love coding but I don’t love life
更多推荐
所有评论(0)