准备环境:参考 https://blog.csdn.net/weixin_44141284/article/details/121553749
修改ES解压目录/config/elasticsearch.yml文件,防止cors,末尾需要添加
http.cors.enabled: true
http.cors.allow-origin: "*"
1. springboot pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!--工具类 start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<!--工具类 end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
2. application.yml配置
server:
port: 9090
spring:
data:
elasticsearch:
client:
reactive:
endpoints: localhost:9200
3. elasticsearch 配置类
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
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;
/**
* @author:
* @Date: 2022-05-17 15:13
* @description:
*/
@Configuration
public class ElasticSearchRestClientConfig extends AbstractElasticsearchConfiguration {
@Value("${spring.data.elasticsearch.client.reactive.endpoints}")
private String clusterNodes;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(clusterNodes)
.build();
return RestClients.create(clientConfiguration).rest();
}
}
4.实体类
package com.space.es.entity;
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;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author:
* @Date: 2022-05-17 15:10
* @description:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(indexName = "product", shards = 3, replicas = 0)
public class ProductEntity implements Serializable {
/**
* 说明一下:这一段是网上拷贝的
* @Field 文档说明
* @Field(type=FieldType.Text, analyzer="ik_max_word") 表示该字段是一个文本,并作最大程度拆分,默认建立索引
* @Field(type=FieldType.Text,index=false) 表示该字段是一个文本,不建立索引
* @Field(type=FieldType.Date) 表示该字段是一个文本,日期类型,默认不建立索引
* @Field(type=FieldType.Long) 表示该字段是一个长整型,默认建立索引
* @Field(type=FieldType.Keyword) 表示该字段内容是一个文本并作为一个整体不可分,默认建立索引
* @Field(type=FieldType.Float) 表示该字段内容是一个浮点类型并作为一个整体不可分,默认建立索引
* date 、float、long都是不能够被拆分的
*/
@Id
private Long id;
@Field(type = FieldType.Keyword)
private String code;
@Field(type = FieldType.Text, analyzer = "simple")
private String pdName;
@Field(type = FieldType.Keyword)
private String category;
@Field(type = FieldType.Double)
private BigDecimal price;
// @Field(type = FieldType.Text, analyzer = "ik_max_word")
@Field(type = FieldType.Text, index = false)
private String descrip;
}
5.dao接口
import com.es.entity.ProductEntity;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
* @author:
* @Date: 2022-05-17 15:23
* @description:
*/
@Repository
public interface ProductRepository extends ElasticsearchRepository<ProductEntity, Long> {
}
6.测试类
package com.space.es.main;
import com.google.common.collect.Lists;
import com.es.entity.ProductEntity;
import com.es.repository.ProductRepository;
import org.elasticsearch.client.RestHighLevelClient;
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.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author:
* @Date: 2022-05-17 15:26
* @description:
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class IndexAndDocTest {
@Autowired
private ProductRepository productRepository;
@Test
public void createIndex(){
System.out.println("项目启动时自动创建索引:index-----");
}
@Test
public void delIndex(){
boolean b = template.deleteIndex(ProductEntity.class);
System.out.println("del index: " + b);
}
@Test
public void save(){
ProductEntity entity = new ProductEntity();
entity.setId(1001L);
entity.setCode("Fruits");
entity.setCategory("水果");
entity.setPdName("香蕉");
entity.setPrice(new BigDecimal("3.5"));
entity.setAddressUrl("url");
productRepository.save(entity);
}
@Test
public void update(){
ProductEntity entity = new ProductEntity();
entity.setId(1002L);
entity.setCode("Fruits");
entity.setCategory("水果");
entity.setPdName("苹果");
entity.setPrice(new BigDecimal("6.5"));
entity.setAddressUrl("url");
productRepository.save(entity);
}
@Test
public void getByIdAndUpdate(){
Optional<ProductEntity> byId = productRepository.findById(1001L);
if (byId.isPresent()) {
System.out.println(byId.get());
ProductEntity entity = byId.get();
entity.setPrice(new BigDecimal("9.9"));
productRepository.save(entity);
}
}
@Test
public void findAll(){
Iterable<ProductEntity> all = productRepository.findAll();
for (ProductEntity entity : all) {
System.out.println(entity);
}
}
@Test
public void deleteDoc(){
Optional<ProductEntity> byId = productRepository.findById(1001L);
if (byId.isPresent()) {
System.out.println(byId.get());
productRepository.delete(byId.get());
}
}
@Test
public void saveAll(){
int count = 10;
for (int i = 0; i < count; i++) {
ProductEntity entity = new ProductEntity();
entity.setId((10L+i));
entity.setCategory("水果");
entity.setCode("Fruits");
entity.setPdName("山竹"+i);
entity.setPrice(new BigDecimal(i+1));
productRepository.save(entity);
}
}
@Test
public void findByPage(){
Sort sort = Sort.by(Sort.Direction.DESC, "id");
int from = 0;
int size = 5;
PageRequest pageRequest = PageRequest.of(from, size, sort);
Iterable<ProductEntity> all = productRepository.findAll(pageRequest);
for (ProductEntity entity : all) {
System.out.println(entity);
}
}
@Test
public void searchQuery(){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "Fruits");
Iterable<ProductEntity> search = productRepository.search(termQueryBuilder);
for (ProductEntity entity : search) {
System.out.println(entity);
}
}
}
---- 添加一些api使用
package com.estest;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.space.estest.dao.ModelConsumeDayRepository;
import com.space.estest.entity.ModelConsumeDayEntity;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
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.Pageable;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Optional;
/**
* @author: me
* @date: 2023-03-30 16:03
* @description:
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class ModelConsumeDayTest {
@Autowired
private ModelConsumeDayRepository modelConsumeDayRepository;
@Autowired
private RestHighLevelClient client;
/**
* 根据主键查询
*/
@Test
public void findById(){
Optional<ModelConsumeDayEntity> byId = modelConsumeDayRepository.findById("Tuo4ioQBiKoXuikCO9hq");
if (byId.isPresent()) {
System.out.println(JSONObject.toJSONString(byId.get()));
}
}
/**
* 查询所有
*/
@Test
public void findAll(){
Pageable pageable = PageRequest.of(0, 10);
Page<ModelConsumeDayEntity> all = modelConsumeDayRepository.findAll(pageable);
for (ModelConsumeDayEntity day : all) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* 根据模型ID查询
*/
@Test
public void findByModelId(){
Pageable pageable = PageRequest.of(0, 10);
Long modelId = 1593516954589261825L;
// QueryBuilder queryBuilder = QueryBuilders.matchQuery("modelId", modelId);
QueryBuilder queryBuilder = QueryBuilders.termQuery("modelId", modelId);
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(queryBuilder, pageable);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* 多字段同时匹配某个值查询
*/
@Test
public void findByMultiFieldMatch(){
Pageable pageable = PageRequest.of(0, 10);
String code = "ZH_00001";
QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(code, "tenementCode", "projectCode");
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(queryBuilder, pageable);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* 根据多个模型id查询
*/
@Test
public void findTermsModelId(){
Pageable pageable = PageRequest.of(0, 10);
Object mId1 = 1593516954589261825L;
Object mId2 = 1583034757731516418L;
QueryBuilder queryBuilder = QueryBuilders.termsQuery("modelId", mId1, mId2);
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(queryBuilder, pageable);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* 指定想要的字段
*/
@Test
public void findSelectField(){
QueryBuilder queryBuilder = QueryBuilders.matchQuery("statisTime", "2023-03-17");
NativeSearchQuery searchS = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withFields("modelId", "consumption", "statisTime")
.withPageable(PageRequest.of(0, 10))
.build();
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(searchS);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* 范围查询
*/
@Test
public void findRange(){
RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("statisTime");
queryBuilder.gte("2023-01-01");
queryBuilder.lte("2023-01-01");
NativeSearchQuery searchS = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withPageable(PageRequest.of(0, 10))
.build();
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(searchS);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* bool 匹配
*/
@Test
public void findByBool(){
RangeQueryBuilder statisTime = QueryBuilders.rangeQuery("statisTime");
statisTime.gte("2023-02-01");
RangeQueryBuilder consumption = QueryBuilders.rangeQuery("consumption");
consumption.gt("0");
RangeQueryBuilder consumptionDep = QueryBuilders.rangeQuery("consumptionDep");
consumptionDep.gt("0");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(statisTime);
queryBuilder.must(consumption);
queryBuilder.must(consumptionDep);
String[] excludes = new String[]{"projectCode"};
FetchSourceFilter sourceFilter = new FetchSourceFilter(null, excludes);
SortBuilder sortBuilder = new FieldSortBuilder("consumption");
sortBuilder.order(SortOrder.DESC);
SortBuilder sortBuilder2 = new FieldSortBuilder("consumptionDep");
sortBuilder2.order(SortOrder.ASC);
NativeSearchQuery searchS = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withSourceFilter(sourceFilter)
.withFilter(QueryBuilders.termQuery("modelId", 1528574486299217922L))
.withPageable(PageRequest.of(0, 10))
.withSort(sortBuilder)
.withSort(sortBuilder2)
.build();
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(searchS);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* bool 多条件匹配查询 模糊,过滤,范围
* term: 精准匹配
* match: 分词匹配
* wildcard: 通配符匹配
* fuzzy: 纠错检索
*
*/
@Test
public void findByBool2(){
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("projectCode", "ZH_00001_XM_00000001");
RangeQueryBuilder statisTime = QueryBuilders.rangeQuery("statisTime");
statisTime.gte("2023-01-01");
statisTime.lte("2023-02-28");
FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("modelName", "气");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(matchQuery);
queryBuilder.must(statisTime);
queryBuilder.must(fuzzyQuery);
RangeQueryBuilder consumption = QueryBuilders.rangeQuery("consumption");
consumption.gt("0");
consumption.lt("10");
NativeSearchQuery searchS = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withFilter(consumption)
.withPageable(PageRequest.of(0, 10))
.build();
Iterable<ModelConsumeDayEntity> search = modelConsumeDayRepository.search(searchS);
for (ModelConsumeDayEntity day : search) {
System.out.println(JSONObject.toJSONString(day));
}
}
/**
* bool 多条件匹配查询 模糊,过滤,范围
*/
@Test
public void findAggs() throws IOException {
//1. 创建SearchRequest
SearchRequest request = new SearchRequest("energy_model_statistics_day");
request.types("keyword");
//2. 指定使用的聚合查询方式
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.aggregation(AggregationBuilders.cardinality("agg").field("modelId"));
request.source(builder);
//3. 执行查询
SearchResponse resp = client.search(request, RequestOptions.DEFAULT);
//4. 获取返回结果
Cardinality agg = resp.getAggregations().get("agg");
long value = agg.getValue();
System.out.println(value);
JSONObject.toJSONStringWithDateFormat(request, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat);
}
}