之前尝试了ES原生的RestHighLevelClient进行交互,使用起来觉得不是特别的方便,样板代码不少,尝试使用一下spring-data-elasticsearch
提供的封装方法,查阅了spring-data的官网后发现官网中的内容实在是很少,在此进行整理。首先添加依赖:
POM依赖
<!-- spring相关依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- es相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
此依赖基于es7.6.2,如果需要自行查看相关官方文档,请确定文档版本一致。
template初始化
package com.example.demo.config;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
@Configuration
public class EsConfiguration extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
@Bean
public ElasticsearchRestTemplate elasticsearchRestTemplate(){
return new ElasticsearchRestTemplate(elasticsearchClient());
}
}
这里使用了ElasticsearchRestTemplate
这个类,对应于RestHighLevelClient
,如果要使用ElasticsearchTemplate
,需要使用TransPortClient
进行初始化,该类在7.x的版本中已被标为废弃,不推荐使用。
简单的CRUD
根据ID进行查询
@Test
void testConnection(){
IndexCoordinates index =IndexCoordinates.of("customer");
Object object=elasticsearchOperations.get("1",Object.class,index);
log.info(object);
}
根据Criteria条件进行查询
@Test
public void testSimpleSeach() throws IOException {
IndexCoordinates index =IndexCoordinates.of("customer");
SearchHit<Object> searchHit=elasticsearchOperations.searchOne(
new CriteriaQuery(new Criteria("name").is("ssj")),
Object.class,index);
log.info(searchHit);
}
插入文档
@Test
public void testIndex() throws IOException {
IndexCoordinates index =IndexCoordinates.of("customer");
Custom cu = new Custom();
cu.setName("sdad");
cu.setSex("1");
cu.setDate(new Date());
IndexQuery indexQuery = new IndexQueryBuilder()
.withId("2")
.withObject(cu)
.build();
String documentId = elasticsearchOperations.index(indexQuery,index);
log.info(documentId);
}
@Test
void testIndexWithOutId() throws IOException {
IndexCoordinates index =IndexCoordinates.of("customer");
Custom cu = new Custom();
cu.setName("zhang");
cu.setSex("1");
cu.setDate(new Date());
IndexQuery indexQuery = new IndexQueryBuilder()
.withObject(cu)
.build();
String documentId = elasticsearchOperations.index(indexQuery,index);
log.info(documentId);
}
使用Document注解插入
首先定义一个Pojo
@Document(indexName = "pojo")
public class Pojo {
@Id
private String name;
@Field(name = "sex")
private String sex;
@Field(format = DateFormat.basic_date_time,type= FieldType.Date)
private Date birth;
}
@id
表示会使用该字段的值作为id,type
指定字段类型,format
仅能在类型为date
下使用
@Test
void testIndexPojo() {
Pojo cu = new Pojo();
cu.setName("ssj");
cu.setSex("1");
cu.setBirth(new Date());
elasticsearchOperations.save(cu);
}
执行后会插入如下文档
"hits" : [
{
"_index" : "pojo",
"_type" : "_doc",
"_id" : "ssj",
"_score" : 1.0,
"_source" : {
"_class" : "com.example.demo.pojo.Pojo",
"name" : "ssj",
"sex" : "1",
"birth" : "20201222T093541.222Z"
}
}
]
删除文档
@Test
public void testDeleteDoc() throws IOException {
IndexCoordinates index =IndexCoordinates.of("customer");
String documentId =elasticsearchOperations.delete("2",index);
log.info(documentId);
}
NativeQuery
NativeQuery相当于万金油的存在,可以通过ES原生的QueryBuilder进行查询
join查询
@Test
public void testNativeQuery() {
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(QueryBuilders.matchQuery("name", "ssj"));
IndexCoordinates index =IndexCoordinates.of("customer");
SearchHits<Custom> hits= elasticsearchOperations.search(queryBuilder.build(),Custom.class,index);
hits.getSearchHits().stream().forEach( hit ->{
log.info(hit.getContent());
});
}
@Test
void testParentId() {
IndexCoordinates index =IndexCoordinates.of("join_index");
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
ParentIdQueryBuilder build = JoinQueryBuilders.parentId("parent","1");
queryBuilder.withQuery(build);
SearchHits<Object> hits= elasticsearchOperations.search(queryBuilder.build(),Object.class,index);
hits.getSearchHits().stream().forEach( hit ->{
log.info(hit.getContent());
});
}
aggreate
@Test
void testAgg() {
IndexCoordinates index =IndexCoordinates.of("my-index-join_family");
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
TermsAggregationBuilder build = AggregationBuilders.terms("agg-name").field("name");
queryBuilder.addAggregation(build);
SearchHits<Object> hits= elasticsearchOperations.search(queryBuilder.build(),Object.class,index);
Map<String, Aggregation> map = hits.getAggregations().getAsMap();
Terms terms = (Terms) map.get("agg-name");
terms.getBuckets().forEach(bucket -> {
System.out.println(bucket.getKeyAsString() + " " + bucket.getDocCount());
});
}