Elasticsearch与Spring的集成
目前常见的Elasticsearch Java API有四类client连接方式:
- TransportClient(不推荐):Elasticsearch原生的api,TransportClient可以支持2.x,5.x版本,TransportClient将会在 Elasticsearch7.0弃用并在8.0中完成删除。
- RestClient:ES官方推荐使用。
- Jest(不推荐):是Java社区开发的,是Elasticsearch的Java Http Rest客户端。
- Spring Data Elasticsearch:与Spring生态对接,可以在web系统中整合到Spring中使用,与SpringBoot、SpringData 版本容易冲突,而且往往很难跟上Elasticsearch版本的更新,比如SpringBoot目前的2.3.1.RELEASE,所支持Elasticsearch7.6.2。
从使用上来说,Spring Data的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如 MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率,也就是说,Spring Data想要把对任何数据的访问都抽象为类似接口,这就导致了Spring Data Elasticsearch在基本查询上没问题,但是复杂查询(模糊、通配符、match查询、聚集查询等)就显得力不从心了,此时,我们还是只能使用原生查询。
所以我们把精力放在REST Client上,Java REST Client有Low Level和High Level两种:
- Java Low Level REST Client:使用该客户端需要将HTTP请求的body手动拼成JSON格式,HTTP响应也必须将返回的JSON数据手动封装成对象,使用上更为原始。
- Java High Level REST Client:该客户端基于Low Level客户端实现,提供API解决Low Level客户端需要手动转换数据格式的问题。
ES的官网已经提供了非常详尽的API参考手册,参见
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html
Java Low Level REST Client的使用
pom.xml中引入依赖,注意依赖的版本与Elasticsearch保持一致:
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.7.0</version>
</dependency>
演示代码:
package com.morris.es.low;import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;import java.io.IOException;public class LowDemo {public static void main(String[] args) throws IOException {RestClient restClient = RestClient.builder(new HttpHost("10.0.44.5", 9200, "http")).build();String indexName = "low_test";String docId = "1";createIndex(restClient, indexName);addDoc(restClient, indexName, docId);queryDoc(restClient, indexName, docId);restClient.close();}private static void createIndex(RestClient restClient, String indexName) throws IOException {Request request = new Request("PUT", indexName);Response response = restClient.performRequest(request);System.out.println(response);}private static void addDoc(RestClient restClient, String indexName, String docId) throws IOException {String jsonString = "{" +"\"msg\":\"Java Low Level REST Client\"" +"}";HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);Request request = new Request("PUT", indexName + "/_doc/" + docId);request.setEntity(entity);Response response = restClient.performRequest(request);System.out.println(response);}private static void queryDoc(RestClient restClient, String indexName, String docId) throws IOException {Request request = new Request("get", indexName + "/_doc/" + docId);Response response = restClient.performRequest(request);System.out.println(response.getEntity());}}
Java High Level REST Client
pom.xml中引入依赖,注意依赖的版本与Elasticsearch保持一致:
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.4.0</version>
</dependency>
获得连接:
RestClientBuilder restClientBuilder =RestClient.builder(new HttpHost("10.0.73.146", 9200, "http"));
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
索引的管理
创建索引
DSL:
put high_test/_mappings
{"properties": {"age": {"type": "integer"},"content": {"type": "text"},"firstName": {"type": "keyword"},"secondName": {"type": "keyword"}}
}
代码如下:
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().field("properties").startObject().field("firstName").startObject().field("type", "keyword").endObject().field("secondName").startObject().field("type", "keyword").endObject().field("age").startObject().field("type", "integer").endObject().field("content").startObject().field("type", "text").endObject().endObject().endObject();CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
createIndexRequest.mapping(xContentBuilder);CreateIndexResponse createIndexResponse= restHighLevelClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);
System.out.println(createIndexResponse.index());
System.out.println(createIndexResponse.isAcknowledged());
索引是否存在
DSL:
HEAD high_test
代码如下:
GetIndexRequest createIndexRequest = new GetIndexRequest(indexName);
boolean exists = restHighLevelClient.indices().exists(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(exists);
删除索引
DSL:
DELETE high_test
代码如下:
DeleteIndexRequest createIndexRequest = new DeleteIndexRequest(indexName);
AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(acknowledgedResponse.isAcknowledged());
文档的管理
创建文档
DSL:
put high_test/_doc/777
{"age": 18,"content": "hello world","firstName": "morris","id": 666,"secondName": "chen"
}
代码如下:
User user = new User();
user.setId(666L);
user.setFirstName("morris");
user.setSecondName("chen");
user.setAge(18);
user.setContent("hello world");IndexRequest indexRequest = new IndexRequest(indexName);
indexRequest.id(String.valueOf(user.getId()));
indexRequest.source(JSON.toJSONString(user), XContentType.JSON);
IndexResponse indexResponse =restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
if (indexResponse != null) {String id = indexResponse.getId();String index = indexResponse.getIndex();System.out.println(id);System.out.println(index);if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {System.out.println("新增文档成功");} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {System.out.println("覆盖文档成功");}
}
查询文档
DSL:
get high_test/_doc/666
代码如下:
GetRequest getRequest = new GetRequest(indexName, "666");
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSource());
修改文档
DSL:
post high_test/_update/666
{"doc": {"name": "morris131"},"doc_as_upsert": true
}
代码如下:
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
xContentBuilder.startObject();
{xContentBuilder.field("name", "morris131");
}
xContentBuilder.endObject();
UpdateRequest request =new UpdateRequest(indexName, "666").doc(xContentBuilder);
request.docAsUpsert(true);
request.fetchSource(true);/*在应答里包含当前文档的内容*/
UpdateResponse updateResponse =restHighLevelClient.update(request, RequestOptions.DEFAULT);
GetResult getResult = updateResponse.getGetResult();
if (getResult.isExists()) {String sourceAsString = getResult.sourceAsString();System.out.println(sourceAsString);
} else {System.out.println("更新失败");
}
删除文档
DSL:
DELETE high_test/_doc/777
代码如下:
DeleteRequest deleteRequest = new DeleteRequest(indexName, "666");
DeleteResponse deleteResponse =restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {System.out.println("文档不存在");
} else {System.out.println("删除成功");
}
普通搜索
DSL:
post kibana_sample_data_flights/_search
{"query": {"match_all": {}},"_source": {"includes": ["Origin*","*Weather"]},"sort": {"DistanceKilometers": "asc","FlightNum": "desc"},"from": 0,"size": 5
}
代码如下:
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from(0);
searchSourceBuilder.size(5);
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
String[] includeFields = new String[]{"Origin*","*Weather"};
searchSourceBuilder.fetchSource(includeFields,null);
searchSourceBuilder.sort(new FieldSortBuilder("DistanceKilometers").order(SortOrder.ASC));
searchSourceBuilder.sort(new FieldSortBuilder("FlightNum").order(SortOrder.DESC));
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
for(SearchHit hit:hits){String src = hit.getSourceAsString();System.out.println(src);
}
聚合搜索
DSL:
post kibana_sample_data_flights/_search?filter_path=aggregations
{"query": {"term": {"OriginCountry": "CN"}},"aggs": {"month_price_histogram": {"date_histogram": {"field": "timestamp","fixed_interval": "30d"},"aggs": {"avg_delay": {"avg": {"field": "FlightDelayMin"}}}}}
}
代码如下:
SearchRequest searchRequest = new SearchRequest();searchRequest.indices(indexName);/*query部分*/SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.termQuery("OriginCountry", "CN"));/*聚集部分*/
DateHistogramAggregationBuilder date_price_histogram= AggregationBuilders.dateHistogram("month_price_histogram");
date_price_histogram.field("timestamp").fixedInterval(DateHistogramInterval.days(30));
date_price_histogram.subAggregation(AggregationBuilders.avg("avg_delay").field("FlightDelayMin")
);
searchSourceBuilder.aggregation(date_price_histogram);
searchRequest.source(searchSourceBuilder);JSONArray jsonArray = new JSONArray();SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {String aggString = JSON.toJSONString(aggregation);jsonArray.add(JSON.parseObject(aggString));List<? extends Histogram.Bucket> buckets= ((Histogram) aggregation).getBuckets();for (Histogram.Bucket bucket : buckets) {System.out.println("--------------------------------------");System.out.println(bucket.getKeyAsString());System.out.println(bucket.getDocCount());ParsedAvg parsedAvg= (ParsedAvg) bucket.getAggregations().getAsMap().get("avg_delay");System.out.println(parsedAvg.getValueAsString());}
}
Spring Data Elasticsearch
引入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId><version>2.6.1</version>
</dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.15.2</version>
</dependency>
配置文件中指定Elasticsearch的host:
spring.elasticsearch.uris=http://10.0.73.146:9200
搜索代码如下:
@Resource
private ElasticsearchOperations elasticsearchOperations;@GetMapping("search")
public String search() {Criteria criteria = new Criteria("agent").matches("firefox");Query query = new CriteriaQuery(criteria);query.setPageable(Pageable.ofSize(5).withPage(1));query.addSort(Sort.by("timestamp").descending());IndexCoordinates indexCoordinates = IndexCoordinates.of("kibana_sample_data_logs");SearchHits<Log> searchHits = elasticsearchOperations.search(query, Log.class, indexCoordinates);for (SearchHit<Log> searchHit : searchHits.getSearchHits()) {System.out.println(searchHit.getContent());}return "OK";
}
Elasticsearch与Spring的集成相关推荐
- Spring Boot 集成 Elasticsearch 实战
今天讲解下如何使用 Spring Boot 结合 ES. 可以在 ES 官方文档中发现,ES 为 Java REST Client 提供了两种方式的 Client:Java Low Level Cli ...
- springboot整合es_[ElasticSearch从入门到场景实战]spring boot集成SpringData操作es
人生起起伏伏,有风光无限日,也有落魄失魂时,人在低谷时,唯有"熬过去,才会赢" 前言 Elasticsearch的Spring Data是Spring Data项目的一部分,Spr ...
- 第 4-8 课:Spring Boot 集成 ElasticSearch
ElasticSearch 是⼀个开源的搜索引擎,建⽴在⼀个全⽂搜索引擎库 Apache Lucene™ 基础之上. Lucene 可以说是当下最先进.⾼性能.全功能的搜索引擎库--⽆论是开源还是私有 ...
- Spring Boot 集成 Elasticsearch
Elasticsearch (简称ES) 是一个基于 Lucene 的分布式.高扩展.高实时的搜索与数据分析引擎.本章介绍 Spring Boot 应用集成 Elasticsearch ,通过 Spr ...
- ElasticSearch——Spring Boot 集成 ES 操作详解
文章目录 ElasticSearch--Spring Boot 集成 ES 操作详解 1.SpringBoot 集成 ES 2.索引的API操作详解 3.文档的API操作详解 ElasticSearc ...
- 【Java进阶】Spring Boot集成ES
目录 spring boot集成ES ElasticSearchConfig 测试文档的基本操作 Elasticsearch Clients 文档 spring boot集成ES Java REST ...
- Kafka 入门和 Spring Boot 集成
2019独角兽企业重金招聘Python工程师标准>>> Kafka 入门和 Spring Boot 集成 概述 kafka 是一个高性能的消息队列,也是一个分布式流处理平台(这里的流 ...
- ElasticSearch 在 Spring 项目中的实践
前言 ElasticSearch简称es,是一个开源的高扩展的分布式全文检索引擎. 它可以近乎实时的存储.检索数据,其扩展性很好,ElasticSearch是企业级应用中较为常见的技术. 下面和大家分 ...
- spring boot 集成sleuth
spring boot 集成sleuth 1. 理论 1.1 sleuth是什么 1.2 sleuth有哪些 1.3 链路追踪的一些基本概念 1.4 zipkin的组成 2. zipkin 实例 2. ...
最新文章
- NeHe OpenGL第三十五课:播放AVI
- git记住用户名和密码
- biztalk adapter for mysql_BizTalk Schedule Adapter的使用
- php中public放什么,PHP中常用关键字public, private, protected, static...
- Kafka(1)-概述
- 读书笔记--对象、实例、原型、继承
- 我国对计算机信息系统安全主要是采取,附录信息网络安全监察法规概述二.doc...
- Android启动过程五个步骤,Android启动流程、app启动原理
- (软件工程复习核心重点)第四章总体设计-第二节:设计原理
- python threading.Thread
- Asp.net MVC代替php
- Golang AES 加解密
- 安装详细步骤win7_windows安装器怎么安装原版win7【详细教程】
- Oracle 12c CDB和PDB的切换
- 如何用PPT制作一份数据图表?
- SEO优化_如何伪原创文章方法
- 论文复审意见及实验规划
- Python File(文件) 方法
- jupyter安装php,如何安装jupyter
- jupyter常用快捷键一览