一、前言
上一篇我们通过kibana的可视化界面,对es的索引以及文档的常用操作做了毕竟详细的总结,本篇将介绍如何使用java完成对es的操作,这也是实际开发中将要涉及到的。
二、java操作es的常用模式
目前,开发中使用java操作es,不管是框架集成,还是纯粹的使用es的api,主要通过下面两种方式:
-
rest-api,主流的像 RestHighLevelClient ;
-
与springboot集成时的jpa操作,主要是 ElasticsearchRepository 相关的api;
上面两种模式的api在开发中都可以方便的使用,相比之下,RestHighLevelClient相关的api灵活性更高,而ElasticsearchRepository 底层做了较多的封装,学习和使用的成本更低,上手更快。
接下来将对上面的两种操作模式做一个详细的总结,本篇所述的es基于7.6.2版本,配合的kibana也为7.6.2版本。
三、rest-api 操作
1、前置准备
导入依赖
导入核心依赖,主要是es的rest依赖,其他的可以根据自己的需要导入;
-
<dependencies>
-
-
<dependency>
-
<groupId>org.apache.logging.log4j</groupId>
-
<artifactId>log4j-api</artifactId>
-
<version>
2.11
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.apache.logging.log4j</groupId>
-
<artifactId>log4j-core</artifactId>
-
<version>
2.11
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.apache.logging.log4j</groupId>
-
<artifactId>log4j-core</artifactId>
-
<version>
2.8
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.apache.logging.log4j</groupId>
-
<artifactId>log4j-jcl</artifactId>
-
<version>
2.11
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>commons-logging</groupId>
-
<artifactId>commons-logging</artifactId>
-
<version>
1.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.elasticsearch</groupId>
-
<artifactId>elasticsearch</artifactId>
-
<version>
7.6
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.elasticsearch.client</groupId>
-
<artifactId>elasticsearch-rest-high-level-client</artifactId>
-
<version>
7.6
.2</version>
-
</dependency>
-
-
<dependency>
-
<groupId>com.fasterxml.jackson.core</groupId>
-
<artifactId>jackson-databind</artifactId>
-
<version>
2.9
.9</version>
-
</dependency>
-
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
<version>
4.12</version>
-
</dependency>
-
-
-
</dependencies>
es连接测试
为了确保后续的所有实验能够正常进行,建议先通过下面的程序测试下是否能够连接es服务;
-
import org.apache.http.HttpHost;
-
import org.elasticsearch.client.RestClient;
-
import org.elasticsearch.client.RestHighLevelClient;
-
-
import java.io.IOException;
-
-
public
class
EsClientTest {
-
-
public
static
void
main
(String[] args)
throws IOException {
-
RestHighLevelClient
esClient
=
new
RestHighLevelClient(
-
RestClient.builder(
new
HttpHost(
"IP",
9200,
"http"))
-
);
-
System.out.println(
"success");
-
esClient.close();
-
}
-
-
}
运行上面的代码,出现下面的效果说明连接成功
2、索引相关操作api的使用
为了减少连接相关的编码,我们将es的client提出到全局的静态变量中,其他方法中就可以直接引用了
-
public
static RestHighLevelClient esClient;
-
-
static {
-
esClient =
new
RestHighLevelClient(
-
RestClient.builder(
new
HttpHost(
"IP",
9200,
"http"))
-
);
-
}
2.1 创建索引
-
/**
-
* 创建索引
-
* @throws IOException
-
*/
-
public
static
void
createIndex
()
throws IOException {
-
CreateIndexRequest
createIndexRequest
=
new
CreateIndexRequest(
"user");
-
CreateIndexResponse
indexResponse
= esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
-
boolean
acknowledged
= indexResponse.isAcknowledged();
-
System.out.println(
"索引创建状态:" + acknowledged);
-
}
main方法中调用方法即可
-
public
static
void
main
(String[] args)
throws IOException {
-
System.out.println(
"connect success");
-
createIndex();
-
esClient.close();
-
}
运行main创建索引
通过kibana查询确认索引是否创建成功
2.2 获取索引
-
/**
-
* 索引信息查询
-
* @throws IOException
-
*/
-
public
static
void
getIndex
()
throws IOException {
-
GetIndexRequest
getIndexRequest
=
new
GetIndexRequest(
"user");
-
GetIndexResponse
getIndexResponse
= esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
-
System.out.println(getIndexResponse.getAliases());
-
System.out.println(getIndexResponse.getMappings());
-
System.out.println(getIndexResponse.getSettings());
-
}
2.3 删除索引
-
/**
-
* 删除索引
-
* @throws IOException
-
*/
-
public
static
void
deleteIndex
()
throws IOException {
-
DeleteIndexRequest
getIndexRequest
=
new
DeleteIndexRequest(
"user");
-
AcknowledgedResponse
delete
= esClient.indices().delete(getIndexRequest, RequestOptions.DEFAULT);
-
System.out.println(
"索引删除状态:" + delete.isAcknowledged());
-
}
3、文档常用操作api的使用
在实际开发过程中,对于文档的操作更为的频繁,接下来演示与es文档相关的操作api。
前置准备
-
public
static
ObjectMapper
objectMapper
=
new
ObjectMapper();
-
-
public
static RestHighLevelClient esClient;
-
static {
-
esClient =
new
RestHighLevelClient(
-
RestClient.builder(
new
HttpHost(
"IP",
9200,
"http"))
-
);
-
}
用于测试使用的对象
-
public
class
User {
-
-
private String name;
-
private String sex;
-
private Integer age;
-
-
private Integer salary;
-
-
public
User
() {
-
}
-
-
public
User
(String name, String sex, Integer age, Integer salary) {
-
this.name = name;
-
this.sex = sex;
-
this.age = age;
-
this.salary = salary;
-
}
-
-
public Integer
getSalary
() {
-
return salary;
-
}
-
-
public
void
setSalary
(Integer salary) {
-
this.salary = salary;
-
}
-
-
public String
getName
() {
-
return name;
-
}
-
-
public
void
setName
(String name) {
-
this.name = name;
-
}
-
-
public String
getSex
() {
-
return sex;
-
}
-
-
public
void
setSex
(String sex) {
-
this.sex = sex;
-
}
-
-
public Integer
getAge
() {
-
return age;
-
}
-
-
public
void
setAge
(Integer age) {
-
this.age = age;
-
}
-
}
3.1 索引添加文档
注意:实际开发中,user对象应该作为参数传入【可以基于此做进一步的封装】
-
/**
-
* 添加数据
-
* @throws Exception
-
*/
-
public
static
void
add
()
throws Exception{
-
IndexRequest
indexRequest
=
new
IndexRequest();
-
indexRequest.index(
"user").id(
"1008");
-
User
user
=
new
User();
-
user.setName(
"孙二娘");
-
user.setAge(
23);
-
user.setSex(
"女");
-
user.setSalary(
7000);
-
-
String
userData
= objectMapper.writeValueAsString(user);
-
indexRequest.source(userData,XContentType.JSON);
-
//插入数据
-
IndexResponse
response
= esClient.index(indexRequest, RequestOptions.DEFAULT);
-
System.out.println(response.status());
-
System.out.println(response.getResult());
-
}
在main方法调用执行下该方法
-
public
static
void
main
(String[] args)
throws Exception {
-
add();
-
esClient.close();
-
}
可以通过kibana查询检查下数据是否添加成功
3.2 修改文档
-
/**
-
* 修改数据
-
* @throws Exception
-
*/
-
public
static
void
update
()
throws Exception{
-
UpdateRequest
request
=
new
UpdateRequest();
-
request.index(
"user").id(
"1008");
-
request.doc(XContentType.JSON,
"name",
"母夜叉");
-
//插入数据
-
UpdateResponse
response
= esClient.update(request, RequestOptions.DEFAULT);
-
System.out.println(response.getResult());
-
}
3.3 删除文档
-
/**
-
* 删除
-
* @throws Exception
-
*/
-
public
static
void
delete
()
throws Exception{
-
DeleteRequest
request
=
new
DeleteRequest();
-
request.index(
"user").id(
"1008");
-
//插入数据
-
DeleteResponse
delete
= esClient.delete(request, RequestOptions.DEFAULT);
-
System.out.println(delete.getResult());
-
}
3.4 批量添加文档
有些情况下,单条插入效率太低,可以使用es的批量插入功能一次性添加多条数据
-
/**
-
* 批量添加
-
* @throws Exception
-
*/
-
public
static
void
batchInsert
()
throws Exception{
-
-
BulkRequest
bulkRequest
=
new
BulkRequest();
-
-
User
user1
=
new
User(
"关羽",
"男",
33,
5500);
-
String
userData1
= objectMapper.writeValueAsString(user1);
-
IndexRequest
indexRequest1
=
new
IndexRequest().index(
"user").id(
"1002").source(userData1, XContentType.JSON);
-
-
bulkRequest.add(indexRequest1);
-
-
User
user2
=
new
User(
"黄忠",
"男",
50,
8000);
-
String
userData2
= objectMapper.writeValueAsString(user2);
-
IndexRequest
indexRequest2
=
new
IndexRequest().index(
"user").id(
"1003").source(userData2, XContentType.JSON);
-
bulkRequest.add(indexRequest2);
-
-
User
user3
=
new
User(
"黄忠2",
"男",
49,
10000);
-
String
userData3
= objectMapper.writeValueAsString(user3);
-
IndexRequest
indexRequest3
=
new
IndexRequest().index(
"user").id(
"1004").source(userData3, XContentType.JSON);
-
bulkRequest.add(indexRequest3);
-
-
User
user4
=
new
User(
"赵云",
"男",
33,
12000);
-
String
userData4
= objectMapper.writeValueAsString(user4);
-
IndexRequest
indexRequest4
=
new
IndexRequest().index(
"user").id(
"1005").source(userData4, XContentType.JSON);
-
bulkRequest.add(indexRequest4);
-
-
User
user5
=
new
User(
"马超",
"男",
38,
20000);
-
String
userData5
= objectMapper.writeValueAsString(user5);
-
IndexRequest
indexRequest5
=
new
IndexRequest().index(
"user").id(
"1006").source(userData5, XContentType.JSON);
-
bulkRequest.add(indexRequest5);
-
-
User
user6
=
new
User(
"关羽",
"男",
41,
27000);
-
String
userData6
= objectMapper.writeValueAsString(user6);
-
IndexRequest
indexRequest6
=
new
IndexRequest().index(
"user").id(
"1007").source(userData6, XContentType.JSON);
-
bulkRequest.add(indexRequest6);
-
-
BulkResponse
bulkResponse
= esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
-
System.out.println(bulkResponse.status());
-
System.out.println(bulkResponse.getItems());
-
}
3.5 批量删除
可以通过批量操作一次性删除多条数据
-
/**
-
* 批量删除
-
* @throws Exception
-
*/
-
public
static
void
batchDelete
()
throws Exception{
-
BulkRequest
bulkRequest
=
new
BulkRequest();
-
DeleteRequest
indexRequest1
=
new
DeleteRequest().index(
"user").id(
"1002");
-
DeleteRequest
indexRequest2
=
new
DeleteRequest().index(
"user").id(
"1003");
-
DeleteRequest
indexRequest3
=
new
DeleteRequest().index(
"user").id(
"1004");
-
DeleteRequest
indexRequest4
=
new
DeleteRequest().index(
"user").id(
"1005");
-
DeleteRequest
indexRequest5
=
new
DeleteRequest().index(
"user").id(
"1006");
-
DeleteRequest
indexRequest6
=
new
DeleteRequest().index(
"user").id(
"1007");
-
-
bulkRequest.add(indexRequest1);
-
bulkRequest.add(indexRequest2);
-
bulkRequest.add(indexRequest3);
-
bulkRequest.add(indexRequest4);
-
bulkRequest.add(indexRequest5);
-
bulkRequest.add(indexRequest6);
-
-
BulkResponse
bulkResponse
= esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
-
System.out.println(bulkResponse.status());
-
System.out.println(bulkResponse.getItems());
-
}
4、文档搜索相关api的使用
我们知道es最强大的功能就是文档检索了,接下来演示下与es文档查询相关的常用API的操作;
4.1 查询某个索引下的所有数据
-
/**
-
* 查询某个索引下的所有数据
-
* @throws Exception
-
*/
-
public
static
void
searchIndexAll
()
throws Exception{
-
SearchRequest
request
=
new
SearchRequest();
-
request.indices(
"user");
-
// 索引中的全部数据查询
-
SearchSourceBuilder
query
=
new
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
-
request.source(query);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
-
}
执行一下对该方法的调用
这个效果和在kibana中下面的操作效果是一样的
4.2 批量查询多条数据
针对那种需要一次性查出多条数据的场景可以考虑使用
-
MultiGetRequest
multiGetRequest
=
new
MultiGetRequest();
-
multiGetRequest.add(
"user",
"1002");
-
multiGetRequest.add(
"user",
"1003");
-
MultiGetResponse
responses
= esClient
-
.mget(multiGetRequest, RequestOptions.DEFAULT);
-
-
Iterator<MultiGetItemResponse> iterator = responses.iterator();
-
while (iterator.hasNext()){
-
MultiGetItemResponse
next
= iterator.next();
-
System.out.println(next.getResponse().getSourceAsString());
-
}
4.3 根据条件精准查询
根据性别查询,有点类似于mysql 中的 where sex='女' 这样的效果
-
TermQueryBuilder
ageQueryBuilder
= QueryBuilders.termQuery(
"sex",
"女");
-
SearchSourceBuilder
query
=
new
SearchSourceBuilder().query(ageQueryBuilder);
-
request.source(query);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.4 分页查询
考察from + size的使用
-
SearchSourceBuilder
sourceBuilder
=
new
-
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
-
sourceBuilder.from(
0).size(
3);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.5 查询结果按照某个字段进行排序
将查询结果按照age进行排序
-
SearchSourceBuilder
sourceBuilder
=
new
-
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
-
sourceBuilder.sort(
"age",SortOrder.ASC);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.6 查询结果过滤某些字段
类似于mysql中只查询某个表的部分字段
-
SearchSourceBuilder
sourceBuilder
=
new
-
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
-
request.source(sourceBuilder);
-
String[] includes = {
"name",
"sex"};
-
String[] excludes = {
"age"};
-
sourceBuilder.fetchSource(includes,excludes);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.7 多条件查询
es可以像mysql那样组合多个条件进行查询,考察对BoolQuery的使用,如下:查询性别为难男,年龄在35到45之间的用户;
-
BoolQueryBuilder
boolQueryBuilder
= QueryBuilders.boolQuery();
-
boolQueryBuilder.must(QueryBuilders.matchQuery(
"sex",
"男"));
-
boolQueryBuilder.must(QueryBuilders.rangeQuery(
"age").lt(
45).gt(
35));
-
sourceBuilder.query(boolQueryBuilder);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.8 范围查询
-
SearchSourceBuilder
sourceBuilder
=
new
SearchSourceBuilder();
-
RangeQueryBuilder
rangeQueryBuilder
=
-
QueryBuilders.rangeQuery(
"age").gte(
35).lte(
45);
-
sourceBuilder.query(rangeQueryBuilder);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.9 模糊查询
-
SearchSourceBuilder
sourceBuilder
=
new
SearchSourceBuilder();
-
FuzzyQueryBuilder
fuzzyQueryBuilder
=
-
QueryBuilders.fuzzyQuery(
"name",
"黄忠")
-
.fuzziness(Fuzziness.ONE);
-
sourceBuilder.query(fuzzyQueryBuilder);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.10 高亮查询
-
SearchSourceBuilder
sourceBuilder
=
new
SearchSourceBuilder();
-
TermQueryBuilder
ageQueryBuilder
= QueryBuilders.termQuery(
"age",
33);
-
HighlightBuilder
highlightBuilder
=
new
HighlightBuilder();
-
highlightBuilder.preTags(
"<font color='red'>");
-
highlightBuilder.postTags(
"</font>");
-
highlightBuilder.field(
"name");
-
sourceBuilder.highlighter(highlightBuilder);
-
sourceBuilder.query(ageQueryBuilder);
-
request.source(sourceBuilder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.11 多字段查询multi_match
这个用法表示从多个字段中匹配某个关键字
-
SearchSourceBuilder
builder
=
new
SearchSourceBuilder();
-
MultiMatchQueryBuilder
multiMatchQuery
= QueryBuilders.multiMatchQuery(
"黄忠",
"name",
"sex");
-
multiMatchQuery.operator(Operator.OR);
-
builder.query(multiMatchQuery);
-
request.source(builder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.12 聚合查询
-
SearchSourceBuilder
builder
=
new
SearchSourceBuilder();
-
AggregationBuilder
aggregationBuilder
= AggregationBuilders.max(
"maxAge").field(
"age");
-
builder.aggregation(aggregationBuilder);
-
request.source(builder);
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
4.13 分组查询
-
SearchSourceBuilder
builder
=
new
SearchSourceBuilder();
-
AggregationBuilder
aggregationBuilder
= AggregationBuilders.terms(
"ageGroup").field(
"age");
-
builder.aggregation(aggregationBuilder);
-
request.source(builder);
-
-
SearchResponse
response
= esClient.search(request, RequestOptions.DEFAULT);
-
System.out.println(response.getHits().getHits());
-
System.out.println(response.getHits().getTotalHits());
-
SearchHits
hits
= response.getHits();
-
for (SearchHit searchHit : hits){
-
System.out.println(searchHit.getSourceAsString());
-
}
四、与springboot 整合
es提供了与spring,springboot快速整合的第三方SDK,接下来以spring-data为例进行说明;
spring-boot-starter-data-elasticsearch 与spring其他相关的jpa方式使用类似,封装了丰富的API接口,客户只需要继承其提供的接口,就能方便的使用内置的API
前置准备
本地创建一个maven工程
1、导入核心依赖
-
<parent>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-parent</artifactId>
-
<version>
2.3
.6.RELEASE</version>
-
<relativePath/>
-
</parent>
-
-
<dependencies>
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-devtools</artifactId>
-
<scope>runtime</scope>
-
<optional>
true</optional>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-test</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-test</artifactId>
-
</dependency>
-
</dependencies>
2、核心配置文件
-
# es 服务地址
-
elasticsearch.host=IP
-
# es 服务端口
-
elasticsearch.port=
9200
-
# 配置日志级别,开启 debug 日志
-
logging.level.com.congge=debug
整合过程
1、创建一个实体类
该实体类属于连接es文档与客户端的一个中间转换层,使用过jpa或者mybatis-plus的同学对这个应该不陌生;
-
import lombok.AllArgsConstructor;
-
import lombok.Data;
-
import lombok.NoArgsConstructor;
-
import lombok.ToString;
-
import org.springframework.data.annotation.Id;
-
import org.springframework.data.elasticsearch.annotations.Document;
-
import org.springframework.data.elasticsearch.annotations.Field;
-
import org.springframework.data.elasticsearch.annotations.FieldType;
-
-
@Data
-
@NoArgsConstructor
-
@AllArgsConstructor
-
@ToString
-
@Document(indexName = "shopping", shards = 3, replicas = 1)
-
public
class
Product {
-
//必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id"
-
@Id
-
private Long id;
//商品唯一标识
-
-
/**
-
* type : 字段数据类型
-
* analyzer : 分词器类型
-
* index : 是否索引(默认:true)
-
* Keyword : 短语,不进行分词
-
*/
-
@Field(type = FieldType.Text, analyzer = "ik_max_word")
-
private String title;
//商品名称
-
-
@Field(type = FieldType.Keyword)
-
private String category;
//分类名称
-
-
@Field(type = FieldType.Double)
-
private Double price;
//商品价格
-
-
@Field(type = FieldType.Keyword, index = false)
-
private String images;
//图片地址
-
}
2、提供一个接口,继承ElasticsearchRepository
-
import com.congge.entity.Product;
-
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
-
import org.springframework.stereotype.Repository;
-
-
@Repository
-
public
interface
ProductDao
extends
ElasticsearchRepository<Product, Long>{
-
-
}
3、核心配置类
-
import lombok.Data;
-
import org.apache.http.HttpHost;
-
import org.elasticsearch.client.RestClient;
-
import org.elasticsearch.client.RestClientBuilder;
-
import org.elasticsearch.client.RestHighLevelClient;
-
import org.springframework.boot.context.properties.ConfigurationProperties;
-
import org.springframework.context.annotation.Configuration;
-
//import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
-
-
@ConfigurationProperties(prefix = "elasticsearch")
-
@Configuration
-
@Data
-
public
class
EsConfig
extends
com.congge.config.AbstractElasticsearchConfiguration {
-
-
private String host ;
-
private Integer port ;
-
-
//重写父类方法
-
@Override
-
public RestHighLevelClient
elasticsearchClient
() {
-
RestClientBuilder
builder
= RestClient.builder(
new
HttpHost(host, port));
-
RestHighLevelClient
restHighLevelClient
=
new
-
RestHighLevelClient(builder);
-
return restHighLevelClient;
-
}
-
}
-
import org.elasticsearch.client.RestHighLevelClient;
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
-
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
-
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
-
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
-
-
public
abstract
class
AbstractElasticsearchConfiguration
extends
ElasticsearchConfigurationSupport {
-
-
//需重写本方法
-
public
abstract RestHighLevelClient
elasticsearchClient
();
-
-
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
-
public ElasticsearchOperations
elasticsearchOperations
(ElasticsearchConverter elasticsearchConverter) {
-
return
new
ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
-
}
-
}
模拟测试
接下来通过junit的方式进行测试
1、索引相关的操作测试
-
import com.congge.entity.Product;
-
import org.junit.Test;
-
import org.junit.runner.RunWith;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.boot.test.context.SpringBootTest;
-
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
-
import org.springframework.test.context.junit4.SpringRunner;
-
-
@RunWith(SpringRunner.class)
-
@SpringBootTest
-
public
class
EsIndexTest {
-
-
//注入 ElasticsearchRestTemplate
-
@Autowired
-
private ElasticsearchRestTemplate elasticsearchRestTemplate;
-
-
//创建索引并增加映射配置
-
@Test
-
public
void
createIndex
(){
-
//创建索引,系统初始化会自动创建索引
-
System.out.println(
"创建索引");
-
}
-
-
@Test
-
public
void
deleteIndex
(){
-
//创建索引,系统初始化会自动创建索引
-
boolean
flg
= elasticsearchRestTemplate.deleteIndex(Product.class);
-
System.out.println(
"删除索引 = " + flg);
-
}
-
-
}
基于spring-data的方式,在工程启动的时候,会自动读取实体类相关的注解,自动完成索引的创建,运行下创建索引的测试方法;
然后去到kibana上面确认下是否创建成功;
2、文档相关的操作测试
该测试类中列举了常用的增删改查操作
-
import com.congge.dao.ProductDao;
-
import com.congge.entity.Product;
-
import org.elasticsearch.index.query.QueryBuilders;
-
import org.elasticsearch.index.query.TermQueryBuilder;
-
import org.junit.Test;
-
import org.junit.runner.RunWith;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.boot.test.context.SpringBootTest;
-
import org.springframework.data.domain.Page;
-
import org.springframework.data.domain.PageRequest;
-
import org.springframework.data.domain.Sort;
-
import org.springframework.test.context.junit4.SpringRunner;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
@RunWith(SpringRunner.class)
-
@SpringBootTest
-
public
class
EsDocTest {
-
-
-
@Autowired
-
private ProductDao productDao;
-
-
/**
-
* 新增
-
*/
-
@Test
-
public
void
save
() {
-
Product
product
=
new
Product();
-
product.setId(
2L);
-
product.setTitle(
"ipad mini");
-
product.setCategory(
"ipad");
-
product.setPrice(
1998.0);
-
product.setImages(
"http://ipad.jpg");
-
productDao.save(product);
-
}
-
-
-
//修改
-
@Test
-
public
void
update
(){
-
Product
product
=
new
Product();
-
product.setId(
2L);
-
product.setTitle(
"iphone");
-
product.setCategory(
"mobile");
-
product.setPrice(
6999.0);
-
product.setImages(
"http://www.phone.jpg");
-
productDao.save(product);
-
}
-
-
//根据 id 查询
-
@Test
-
public
void
findById
(){
-
Product
product
= productDao.findById(
2L).get();
-
System.out.println(product);
-
}
-
-
//查询所有
-
@Test
-
public
void
findAll
(){
-
Iterable<Product> products = productDao.findAll();
-
for (Product product : products) {
-
System.out.println(product);
-
}
-
}
-
-
//删除
-
@Test
-
public
void
delete
(){
-
Product
product
=
new
Product();
-
product.setId(
2L);
-
productDao.delete(product);
-
}
-
-
//批量新增
-
@Test
-
public
void
saveAll
(){
-
List<Product> productList =
new
ArrayList<>();
-
for (
int
i
=
0; i <
10; i++) {
-
Product
product
=
new
Product();
-
product.setId(Long.valueOf(i));
-
product.setTitle(
"iphone" + i);
-
product.setCategory(
"mobile");
-
product.setPrice(
5999.0 + i);
-
product.setImages(
"http://www.phone.jpg");
-
productList.add(product);
-
}
-
productDao.saveAll(productList);
-
}
-
-
//分页查询
-
@Test
-
public
void
findByPageable
(){
-
//设置排序(排序方式,正序还是倒序,排序的 id)
-
Sort
sort
= Sort.by(Sort.Direction.DESC,
"id");
-
int currentPage=
0;
//当前页,第一页从 0 开始, 1 表示第二页
-
int
pageSize
=
5;
//每页显示多少条
-
//设置查询分页
-
PageRequest
pageRequest
= PageRequest.of(currentPage, pageSize,sort);
-
//分页查询
-
Page<Product> productPage = productDao.findAll(pageRequest);
-
for (Product Product : productPage.getContent()) {
-
System.out.println(Product);
-
}
-
}
-
-
/**
-
* term 查询
-
* search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
-
*/
-
@Test
-
public
void
termQuery
(){
-
TermQueryBuilder
termQueryBuilder
= QueryBuilders.termQuery(
"title",
"iphone");
-
Iterable<Product> products = productDao.search(termQueryBuilder);
-
for (Product product : products) {
-
System.out.println(product);
-
}
-
}
-
-
/**
-
* term 查询加分页
-
*/
-
@Test
-
public
void
termQueryByPage
(){
-
int currentPage=
0 ;
-
int
pageSize
=
5;
-
//设置查询分页
-
PageRequest
pageRequest
= PageRequest.of(currentPage, pageSize);
-
TermQueryBuilder
termQueryBuilder
= QueryBuilders.termQuery(
"title",
"phone");
-
Iterable<Product> products =
-
productDao.search(termQueryBuilder,pageRequest);
-
for (Product product : products) {
-
System.out.println(product);
-
}
-
}
-
-
}
测试其中批量新增的方法
更多丰富的API接口的使用有兴趣的同学可以基于此继续深入的研究学习。
转载:https://blog.csdn.net/congge_study/article/details/128194887