SpringBoot整合ElasticSearch7.8.1(增删改查索引,增删改查文档)
创建SpringBoot工程,更改pom文件
以下依赖全部使用到了,所以无比全部添加
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ElasticSearch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ElasticSearch</name>
<description>ElasticSearch</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.8.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
编写ElasticSearch配置类
package com.example.config;
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticSearchConfig {
private String host;
private int port;
@Bean
public RestHighLevelClient client() {
return new RestHighLevelClient(RestClient.builder(new HttpHost(host, port, "http")));
}
}
yml配置文件中配置elasticsearch的主机和端口号
elasticsearch:
host: elasticsearch主机
port: elasticsearch端口号
编写项目启动类
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ElasticSearchApplication {
public static void main(String[] args) {
SpringApplication.run(ElasticSearchApplication.class, args);
}
}
使用SpringBoot Test编写测试用例
package com.example;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.dto.Person;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortMode;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@SpringBootTest
class ElasticSearchApplicationTests {
@Autowired
RestHighLevelClient client;
@Test
void contextLoads() {
System.out.println(client);
}
//添加索引
@Test
public void createIndex() throws IOException {
IndicesClient indices = client.indices();
CreateIndexRequest createIndexRequest = new CreateIndexRequest("index_test");
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(createIndexResponse.isAcknowledged());
}
//添加索引并添加映射
@Test
public void addIndexMapping() throws IOException {
IndicesClient indices = client.indices();
CreateIndexRequest createIndexRequest = new CreateIndexRequest("index_test_one");
String mapping = "{
" + " "properties" : {
" + " "address" : {
" + " "type" : "text",
" + " "analyzer" : "ik_max_word"
" + " },
" + " "age" : {
" + " "type" : "long"
" + " },
" + " "name" : {
" + " "type" : "keyword"
" + " }
" + " }
" + " }";
createIndexRequest.mapping(mapping, XContentType.JSON);
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(createIndexResponse.isAcknowledged());
}
//创建索引并添加映射方式2
@Test
public void createIndexAddMapping() throws Exception {
IndicesClient indices = client.indices();
XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("properties").startObject().field("name").startObject().field("index", "true").field("type", "keyword").endObject().field("money").startObject().field("index", "true").field("type", "double").endObject().field("birthday").startObject().field("index", "true").field("type", "date").field("format", "strict_date_optional_time||epoch_millis").endObject().endObject().endObject();
CreateIndexRequest createIndexRequest = new CreateIndexRequest("index_test");
createIndexRequest.mapping(builder);
CreateIndexResponse response = indices.create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
}
//查询索引
@Test
public void getIndex() throws IOException {
IndicesClient indices = client.indices();
GetIndexRequest getIndexRequest = new GetIndexRequest("index_test_one");
GetIndexResponse getIndexResponse = indices.get(getIndexRequest, RequestOptions.DEFAULT);
Map<String, MappingMetadata> mappings = getIndexResponse.getMappings();
for (String key : mappings.keySet()) {
System.out.println("key:" + mappings.get(key).getSourceAsMap());
}
}
//删除索引
@Test
public void deleteIndex() throws IOException {
IndicesClient indices = client.indices();
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("index_test");
AcknowledgedResponse delete = indices.delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
//索引是否存在
@Test
public void existIndex() throws IOException {
IndicesClient indices = client.indices();
GetIndexRequest getIndexRequest = new GetIndexRequest("index_test");
boolean exists = indices.exists(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
//添加文档 使用map作为数据
@Test
public void addDoc() throws IOException {
Map<String, Object> map = new HashMap<>();
map.put("name", "小青");
map.put("money", 300.00);
map.put("birthday", new Date());
IndexRequest request = new IndexRequest("index_test").id("2").source(map);
IndexResponse res = client.index(request, RequestOptions.DEFAULT);
System.out.println(res.getId());
}
//添加文档 使用对象作为数据
@Test
public void addDoc2() throws Exception {
Person person = new Person();
person.setId("4");
person.setName("小李");
person.setAge(20);
person.setAddress("江苏南京");
String data = JSON.toJSONString(person);
IndexRequest indexRequest = new IndexRequest("index_test_one").id(person.getId()).source(data, XContentType.JSON);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.getId());
}
//修改文档
//id存在时修改文档 id不存在时则添加
@Test
public void UpdateDoc() throws Exception {
Person person = new Person();
person.setId("4");
person.setName("小李");
person.setAge(20);
person.setAddress("中国");
String data = JSON.toJSONString(person);
IndexRequest indexRequest = new IndexRequest("index_test_one").id(person.getId()).source(data, XContentType.JSON);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.getId());
}
//根据id查询文档
@Test
public void getDocById() throws Exception {
GetRequest indexRequest = new GetRequest("index_test_one", "4");
GetResponse response = client.get(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.getSourceAsMap());
}
//根据id删除文档
@Test
public void deleteDoc() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("index_test_one", "1");
DeleteResponse respone = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(respone.getId());
}
//按条件查询(普通查询)
@Test
public void queryFind() throws IOException {
SearchRequest searchRequest = new SearchRequest("index_test_one");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//精准查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "小王");
//范围查询 如果是日期则需要在最后加一个format("yyyy-MM-dd")
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").from(19).to(20);
//前缀查询
// PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name", "小");
//通配符查询
// WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("name", "*青");
// //模糊查询
// FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "王");
//按年龄排序
FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("age");
//从小到大排序
fieldSortBuilder.sortMode(SortMode.MIN);
//多条件时使用should连接
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(termQueryBuilder).should(rangeQueryBuilder);
sourceBuilder.query(boolQueryBuilder).sort(fieldSortBuilder);
//设置超时时间
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
String souceAsString = hit.getSourceAsString();
JSONObject jsonObject = JSON.parseObject(souceAsString);
System.out.println(jsonObject);
}
}
//按条件查询(聚合查询)
@Test
public void aggregationQuery() throws Exception {
SearchRequest searchRequest = new SearchRequest("index_test_one");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("by_age").field("age");
sourceBuilder.aggregation(termsAggregationBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
Map<String, Aggregation> stringAggregationMap = aggregations.getAsMap();
ParsedLongTerms parsedLongTerms = (ParsedLongTerms) stringAggregationMap.get("by_age");
List<? extends Terms.Bucket> buckets = parsedLongTerms.getBuckets();
for (Terms.Bucket bucket : buckets) {
Long docCount = bucket.getDocCount();
Number keyAsNumber = bucket.getKeyAsNumber();
System.out.println(keyAsNumber + "岁的有" + docCount + "个");
}
}
//聚合查询求和
@Test
public void aggregationSum() throws Exception {
SearchRequest searchRequest = new SearchRequest("index_test");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("money_total").field("money");
sourceBuilder.aggregation(sumAggregationBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
Sum moneyTotal = aggregations.get("money_total");
Double moneyTotalDouble = moneyTotal.getValue();
System.out.println(moneyTotalDouble);
}
}
需要注意的是GetIndexRequest和CreateIndexRequest的包是org.elasticsearch.client.indices
,而不是包org.elasticsearch.action.admin.indices
,如果引错包,你将会发现create方法显示被弃用、GetIndexRequest方法显示无法传入字符串类型,需要传入StreamInput类型