前言

Elasticsearch官方列出了好几个客户端,如下所示

  • Java Client
  • Java Rest Client(Java High Level REST Client)
  • Java Transport Client

其中Java Rest Client在7.15.0被标记已过时,Java Transport Client暂时没找到在哪个版本被标记过时

注:

  • 官方文档
  • Spring Boot 2.3.12.RELEASE
  • Elasticsearch 7.17.5

Java Client 集成

Java Client在构建对象时支持Build模式以及Lambda两种形式,暴露出来的API为ElasticsearchClient类,通过该类可进行对索引、文档的基本操作。

ElasticsearchClient对象初始化步骤

第一步,引入依赖

<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>7.17.5</version>
</dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency> <dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.0.1</version>
</dependency>

在Spring Boot项目中,如果引入了以下依赖,便不用单独引入jackson-databind依赖了

<!-- 已经包含了jackson-databind -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

第二步,配置ObjectMapper

如果不想自定义ObjectMapper的行为,可以省略,这里主要想要支持LocalDateLocalDateTime类,不然文档中如果包含时间列,反序列成对象时会报错。

在Spring Boot项目中只需加入以下配置即可

package com.wangtao.msgsearch.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; @Component
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer { private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss"; private static final String DATE_PATTERN = "yyyy-MM-dd"; private static final String TIME_PATTERN = "HH:mm:ss"; @Override
public void customize(Jackson2ObjectMapperBuilder builder) {
// 初始化JavaTimeModule
JavaTimeModule javaTimeModule = new JavaTimeModule(); //处理LocalDateTime
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(STANDARD_PATTERN);
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); //处理LocalDate
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter)); //处理LocalTime
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_PATTERN);
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter)); /*
* 1. java.util.Date yyyy-MM-dd HH:mm:ss
* 2. 支持JDK8 LocalDateTime、LocalDate、 LocalTime
* 3. Jdk8Module模块支持如Stream、Optional等类
* 4. 序列化时包含所有字段
* 5. 在序列化一个空对象时时不抛出异常
* 6. 忽略反序列化时在json字符串中存在, 但在java对象中不存在的属性
* 7. 数字序列化成字符穿且调用BigDecimal.toPlainString()方法
*/
builder.simpleDateFormat(STANDARD_PATTERN)
.modules(javaTimeModule, new Jdk8Module())
.serializationInclusion(JsonInclude.Include.ALWAYS)
.failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
}
}

第三步,将ElasticsearchClient对象注册到Spring容器中

package com.wangtao.msgsearch.config;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class ElasticsearchConfig { @Bean
public ElasticsearchClient elasticsearchClient(ObjectMapper objectMapper) {
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200)).build(); ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper(objectMapper)); return new ElasticsearchClient(transport);
}
}

API使用

现在就可以来感受下Elasticsearch Java Client API链式以及lambda风格

先准备测试数据

建立索引

PUT /user
{
"mappings": {
"properties": {
"userId": {
"type": "integer",
"index": true
},
"name": {
"type": "text",
"index": true
},
"age": {
"type": "integer",
"index": true
},
"birthday": {
"type": "date",
"index": true
},
"createTime": {
"type": "date",
"index": false,
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}

插入数据

POST /user/_bulk
{"index": {"_id": 1}}
{"userId": 1, "name" : "zhang san", "age" : 20, "birthday" : "2021-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 2}}
{"userId": 2, "name" : "li si", "age" : 20, "birthday" : "2022-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 3}}
{"userId": 3, "name" : "zhang san shuo", "age" : 25, "birthday" : "2022-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 4}}
{"userId": 4, "name" : "wang wu", "age" : 20, "birthday" : "2021-08-20", "createTime" : "2022-08-20 12:10:30"}

根据文档ID查询数据

lambda表达式

 @GetMapping("/{docId}")
public User getByDocId(@PathVariable String docId) throws IOException {
GetResponse<User> reponse = elasticsearchClient.get(
g -> g.index("user").id(docId),
User.class
);
if (reponse.found()) {
return reponse.source();
} else {
throw new IllegalArgumentException("not found " + docId);
}
}

Build模式

@GetMapping("/getByDocIdFluent/{docId}")
public User getByDocIdFluent(@PathVariable String docId) throws IOException {
GetRequest getRequest = new GetRequest.Builder()
.index("user")
.id(docId)
.build();
GetResponse<User> reponse = elasticsearchClient.get(getRequest, User.class);
if (reponse.found()) {
return reponse.source();
} else {
throw new IllegalArgumentException("not found " + docId);
}
}

搜索操作

实现效果: where name like '%zhang%' and age in (25, 20)

@GetMapping("/search")
public List<User> search() throws IOException {
Query byName = new MatchQuery.Builder()
.field("name")
.query("zhang")
.build()._toQuery();
TermsQueryField termsQueryField = new TermsQueryField.Builder()
.value(Arrays.asList(FieldValue.of(25), FieldValue.of(20)))
.build();
Query inAge = new TermsQuery.Builder()
.field("age")
.terms(termsQueryField)
.build()._toQuery();
Query query = new BoolQuery.Builder()
.must(byName, inAge)
.build()._toQuery();
SearchRequest searchRequest = new SearchRequest.Builder()
.index("user")
.query(query)
.build();
SearchResponse<User> response = elasticsearchClient.search(
searchRequest, User.class);
List<Hit<User>> hits = response.hits().hits();
return hits.stream().map(Hit::source).collect(Collectors.toList());
}

Elasticsearch Java client使用的更多相关文章

  1. Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介.Java REST Client.Java Client.Spri ...

  2. elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    一.ES Client 简介 1. ES是一个服务,采用C/S结构 2. 回顾 ES的架构 3. ES支持的客户端连接方式 3.1 REST API ,端口 9200 这种连接方式对应于架构图中的RE ...

  3. Elasticsearch Java Client连接池

    按照Elasticsearch API,在Java端使用是ES服务需要创建Java Client,但是每一次连接都实例化一个client,对系统的消耗很大,即使在使用完毕之后将client close ...

  4. elasticsearch Java Client用户指南

    这里使用的Java客户端版本是5.1.2,Elasticsearch的版本号也要是5.1.2,否则一些功能可能不支持. 之前介绍过Spring Data Elasticsearch,那里也是使用了本文 ...

  5. elasticsearch java client

    1.集群名相同,且机器处于同一局域网同一网段,es会自动去发现其他的节点.2.集群不在同一局域网同一网段时,只需要在 elasticsearch.yml 中配置目标机器和端口即可discovery.z ...

  6. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI

    目录 引言 Search APIs Search API Search Request 可选参数 使用 SearchSourceBuilder 构建查询条件 指定排序 高亮请求 聚合请求 建议请求 R ...

  7. Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries

    目录 上篇回顾 Building Queries 匹配所有的查询 全文查询 Full Text Queries 什么是全文查询? Match 全文查询 API 列表 基于词项的查询 Term Term ...

  8. Elasticsearch java api操作(一)(Java Low Level Rest Client)

    一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...

  9. [搜索]ElasticSearch Java Api(一) -添加数据创建索引

    转载:http://blog.csdn.net/napoay/article/details/51707023 ElasticSearch JAVA API官网文档:https://www.elast ...

  10. Elasticsearch java api 基本搜索部分详解

    文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...

随机推荐

  1. JZOJ 4318. 【NOIP2015模拟11.5】俄罗斯套娃

    题目大意 求逆序对个数小于等于 \(k\) 的排列数 解析 已经做过很多次了,经典得不能再经典的问题 注意本题很卡空间,要用滚动数组 \(Code\) #include<cstdio> u ...

  2. 【译】.NET 7 中的性能改进(五)

    原文 | Stephen Toub 翻译 | 郑子铭 循环提升和克隆 (Loop Hoisting and Cloning) 我们之前看到PGO是如何与循环提升和克隆互动的,这些优化也有其他改进. 从 ...

  3. Postgresql清理WAL日志

    WAL是Write Ahead Log的简写,和oracle的redo日志类似,存放在$PGDATA/pg_xlog中,10版本以后在$PGDATA/pg_wal目录. 1.如果开启了归档,在目录ar ...

  4. linux 信号 未决信号集和屏蔽信号集

    有的地方,将屏蔽又叫阻塞? 在虚拟地址空间中,内核区的PCB中 有两个64位的值(集合),分别表示64个信号的未决状态(未被处理)和屏蔽与否 kill -l 可以查看linux中的所有信号,共64个 ...

  5. 野火STM32 ADC独立模式单通道采集实验意外

    1 //about calibration 2 //ADC_ResetCalibration(ADC1); 3 //while(ADC_GetResetCalibrationStatus(ADC1) ...

  6. Word17 学生儿童医保扣款方式更新的通知

    1.课程的讲解之前,先来对题目进行分析,首先需要在考生文件夹下,将Wrod素材.docx文件另存为Word.docx,后续操作均基于此文件,否则不得分. 2.这一步非常的简单,打开下载素材文件,在[文 ...

  7. windows自带xbox game bar如何更改录制视频保存位置

      若要更改保存游戏剪辑的位置,请使用文件资源管理器根据需要将"捕获"文件夹移动到电脑上的任意位置. Windows 会将游戏剪辑和屏幕截图保存在该文件夹中(无论移动到哪里).   ...

  8. null和undefine的区别

    null和undefine都是基本数据类型,两种类型都只有一个值. 区别: 1.undefined表示已经声明未定义,null表示的是一个空对象(null并不是空对象,js的typeof会将null判 ...

  9. PV动态供给之nfs

    需求描述:利用nfs实现PV动态供给 前提:部署好nfs服务器  这里地址是 192.168.1.35  path: /ifs/k8s NFS:是一个主流的文件共享服务器. # yum install ...

  10. 关于elasticsearch使用ceph作为存储

    首先关于这个问题本人已经持续关注很长时间了,先说结果--elasticsearch(ES)不适合不适合不适合使用分布式存储.测试环境当然无所谓!!! 以下是相关资料的链接(持续更新): 1.https ...