SpringBoot2.5.6整合Elasticsearch7.12.1

SpringBoot2.5.6整合Elasticsearch7.12.1

下面将通过SpringBoot整合Elasticseach,SpringBoot的版本是2.5.6,Elasticsearch的版本是7.12.1

SpringBoot整合Elasticsearch主要有三种方式,一种是通过elasticsearch-rest-high-level-client,另一

种是通过spring-boot-starter-data-elasticsearch,最后一种是通过transport

RestHighLevelClient 更强大,更灵活,但是不能友好的操作对象,ElasticSearchRepository 对象操作友

好。

官方文档:

https://docs.spring.io/spring-data/elasticsearch/docs/4.0.1.RELEASE/reference/html/#preface

https://spring.io/projects/spring-data-elasticsearch/#learn

https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.2/java-docs.html

1、elasticsearch-rest-high-level-client方式

使用RestHighLevelClient操作

官网地址:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

1.1 引入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.5.6</version><relativePath/></parent><groupId>com.example</groupId><artifactId>spring-boot-elasticsearch1</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-elasticsearch1</name><description>spring-boot-elasticsearch1</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></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.12.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

1.2 添加配置文件EsConfig

package com.example.springbootelasticsearch1.config;import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author zhangshixing* @date 2021年11月09日 21:57*/
@Configuration
public class EsConfig {@Value("${elasticsearch.hostname}")private String hostname;@Value("${elasticsearch.port}")private int port;/*** HighLevelRestConfig*/@Beanpublic RestHighLevelClient restHighLevelClient() {// 如果有多个从节点可以持续在内部new多个HttpHost,参数1是IP,参数2是端口,参数3是通信协议return new RestHighLevelClient(RestClient.builder(new HttpHost(hostname, port, "http")));}
}

1.3 配置yml文件

# es配置
elasticsearch.hostname=127.0.0.1
elasticsearch.port=9200# 默认配置,在本地启动的时候可以不配置
# spring.elasticsearch.rest.uris=http://127.0.0.1:9200

1.4 service

package com.example.springbootelasticsearch1.service;import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.index.reindex.BulkByScrollResponse;import java.io.IOException;/*** @author zhangshixing* @date 2021年11月09日 22:05*/
public interface IRestHighLevelClientService {// 创建索引CreateIndexResponse createIndex() throws IOException;// 删除索引AcknowledgedResponse deleteIndex() throws IOException;// 查看索引是否存在boolean existIndex() throws IOException;// 更新索引的settings配置AcknowledgedResponse updateIndexSettings() throws IOException;// 更新索引的mapping配置AcknowledgedResponse updateIndexMapping() throws IOException;// 新增文档IndexResponse addDocument() throws IOException;// 修改文档UpdateResponse updateDocument() throws IOException;// 根据id删除文档DeleteResponse deleteDocumentById() throws IOException;// 根据条件删除文档BulkByScrollResponse deleteDocumentByCon() throws IOException;// 批量操作文档BulkResponse bulkDocument() throws IOException;// 查询操作SearchResponse searchDocument1() throws IOException;// 查询操作2SearchResponse searchDocument2() throws IOException;// 高亮查询SearchResponse searchDocument3() throws IOException;
}

1.5 serviceImpl

package com.example.springbootelasticsearch1.service.impl;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
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.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
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.PutMappingRequest;
import org.elasticsearch.common.settings.Settings;
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.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** @author zhangshixing* @date 2021年11月09日 22:06*/
@Service
public class RestHighLevelClientServiceImpl implements IRestHighLevelClientService {// 引入RestHighLevelClient@Autowiredprivate RestHighLevelClient restHighLevelClient;// 新建索引@Overridepublic CreateIndexResponse createIndex() throws IOException {String indexName = "student";CreateIndexRequest request = new CreateIndexRequest(indexName.toLowerCase());request.settings(Settings.builder().put("index.number_of_shards", 5).put("index.number_of_replicas", 0));// mapping部分,除了用json字符串来定义外,还可以使用Map或者XContentBuilder// 这里使用XContentBuilderXContentBuilder builder = XContentFactory.jsonBuilder();builder.startObject();{builder.startObject("properties");{builder.startObject("id");{builder.field("type", "integer");}builder.endObject();builder.startObject("name");{builder.field("type", "text");}builder.endObject();builder.startObject("age");{builder.field("type", "integer");}builder.endObject();builder.startObject("description");{builder.field("type", "text");builder.field("analyzer", "ik_max_word");}builder.endObject();builder.startObject("birthday");{builder.field("type", "date");}builder.endObject();}builder.endObject();}builder.endObject();request.mapping(builder);// 同步的方式执行CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);// 异步的方式执行restHighLevelClient.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() {@Overridepublic void onResponse(CreateIndexResponse createIndexResponse1) {System.out.println("执行情况:" + createIndexResponse1);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});return createIndexResponse;}// 删除索引@Overridepublic AcknowledgedResponse deleteIndex() throws IOException {String indexName = "student";DeleteIndexRequest indexRequest = new DeleteIndexRequest(indexName);// 同步执行AcknowledgedResponse delete = restHighLevelClient.indices().delete(indexRequest, RequestOptions.DEFAULT);// 异步执行/*restHighLevelClient.indices().deleteAsync(indexRequest, RequestOptions.DEFAULT, new ActionListener<AcknowledgedResponse>() {@Overridepublic void onResponse(AcknowledgedResponse acknowledgedResponse) {System.out.println("执行情况:" + acknowledgedResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return delete;}// 查看索引是否存在@Overridepublic boolean existIndex() throws IOException {String indexName = "student";GetIndexRequest request = new GetIndexRequest(indexName);// 同步执行boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);// 异步执行/*restHighLevelClient.indices().existsAsync(request, RequestOptions.DEFAULT, new ActionListener<Boolean>() {@Overridepublic void onResponse(Boolean aBoolean) {System.out.println("执行情况:" + aBoolean);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return exists;}// 更新索引的settings配置@Overridepublic AcknowledgedResponse updateIndexSettings() throws IOException {String indexName = "student";UpdateSettingsRequest request = new UpdateSettingsRequest(indexName);String settingKey = "index.number_of_replicas";int settingValue = 2;Settings.Builder settingsBuilder = Settings.builder().put(settingKey, settingValue);request.settings(settingsBuilder);// 是否更新已经存在的settings配置默认falserequest.setPreserveExisting(true);// 更新settings配置(同步)AcknowledgedResponse updateSettingsResponse = restHighLevelClient.indices().putSettings(request, RequestOptions.DEFAULT);// 更新settings配置(异步)/*restHighLevelClient.indices().putSettingsAsync(request, RequestOptions.DEFAULT, new ActionListener<AcknowledgedResponse>() {@Overridepublic void onResponse(AcknowledgedResponse acknowledgedResponse) {System.out.println("执行情况:" + acknowledgedResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return updateSettingsResponse;}// 更新索引的mapping配置@Overridepublic AcknowledgedResponse updateIndexMapping() throws IOException {String indexName = "student";PutMappingRequest request = new PutMappingRequest(indexName);XContentBuilder builder = XContentFactory.jsonBuilder();builder.startObject();{builder.startObject("properties");{// 会在以前索引的基础上新增sex字段builder.startObject("sex");{builder.field("type", "integer");}builder.endObject();}builder.endObject();}builder.endObject();request.source(builder);// 新增mapping配置(同步)AcknowledgedResponse putMappingResponse = restHighLevelClient.indices().putMapping(request, RequestOptions.DEFAULT);// 新增mapping配置(异步)/*restHighLevelClient.indices().putMappingAsync(request, RequestOptions.DEFAULT, new ActionListener<AcknowledgedResponse>() {@Overridepublic void onResponse(AcknowledgedResponse acknowledgedResponse) {System.out.println("执行情况:" + acknowledgedResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return putMappingResponse;}// 新增文档@Overridepublic IndexResponse addDocument() throws IOException {String indexName = "student";IndexRequest request = new IndexRequest(indexName);// id为1的数据request.id("1");Map<String, Object> jsonMap = new HashMap<>();jsonMap.put("id", 1);jsonMap.put("name", "tom");jsonMap.put("age", 24);jsonMap.put("description", "tom是一个好学生");jsonMap.put("birthday", new Date());jsonMap.put("sex", 1);request.source(jsonMap);request.routing("routing");// 同步方式IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);// 异步方式/*restHighLevelClient.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {@Overridepublic void onResponse(IndexResponse indexResponse) {System.out.println("执行情况: " + indexResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return indexResponse;}// 修改文档@Overridepublic UpdateResponse updateDocument() throws IOException {String indexName = "student";// 传入索引名称和需要更新的Document的idUpdateRequest request = new UpdateRequest(indexName, "1");// 更新的内容会与数据本身合并,若存在则更新,不存在则新增// 组装更新内容的数据结构有四种: json字符串、Map、XContentBuilder、Key-Value// json字符串/*String jsonString = "{" +"\"updated\":\"2020-03-29\"," +"\"reason\":\"daily update\"" +"}";request.doc(jsonString);*/// Map/*Map<String, Object> jsonMap = new HashMap<>();jsonMap.put("updated", new Date());jsonMap.put("reason", "daily update");request.doc(jsonMap);*/// XContentBuilder/*XContentBuilder builder = XContentFactory.jsonBuilder();builder.startObject();builder.timeField("updated", new Date());builder.timeField("reason", "daily update");builder.endObject();request.doc(builder);*/// Key-Value,可以包含多个键值对request.doc("description", "tom是一个好学生,考上大学肯定没有问题!");// 同步的方式发送更新请求UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);// 异步方式/*restHighLevelClient.updateAsync(request, RequestOptions.DEFAULT, new ActionListener<UpdateResponse>() {@Overridepublic void onResponse(UpdateResponse updateResponse) {System.out.println("执行情况: " + updateResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return updateResponse;}// 根据id删除文档@Overridepublic DeleteResponse deleteDocumentById() throws IOException {String indexName = "student";DeleteRequest deleteRequest = new DeleteRequest(indexName, "1");// 同步方式DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);// 异步方式/*restHighLevelClient.deleteAsync(deleteRequest, RequestOptions.DEFAULT, new ActionListener<DeleteResponse>() {@Overridepublic void onResponse(DeleteResponse deleteResponse) {System.out.println("执行情况: " + deleteResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return deleteResponse;}// 根据条件删除文档@Overridepublic BulkByScrollResponse deleteDocumentByCon() throws IOException {String indexName = "student";DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(indexName);// 待删除的数据需要满足的条件deleteByQueryRequest.setQuery(new TermQueryBuilder("name", "tom"));// 忽略版本冲突deleteByQueryRequest.setConflicts("proceed");// 同步的方式删除BulkByScrollResponse deleteResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);// 异步的方式/*restHighLevelClient.deleteByQueryAsync(deleteByQueryRequest, RequestOptions.DEFAULT, new ActionListener<BulkByScrollResponse>() {@Overridepublic void onResponse(BulkByScrollResponse bulkByScrollResponse) {System.out.println("执行情况: " + deleteResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return deleteResponse;}// 批量操作文档@Overridepublic BulkResponse bulkDocument() throws IOException {String indexName = "student";BulkRequest request = new BulkRequest();// 普通的PUT操作,相当于全量替换或新增request.add(new IndexRequest(indexName).id("2").source(XContentType.JSON, "name", "zsx", "age", "25"));// 更新操作request.add(new UpdateRequest(indexName, "2").doc(XContentType.JSON, "sex", 1));// 删除操作request.add(new DeleteRequest(indexName, "2"));// 同步操作BulkResponse bulkResponse = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);boolean hasFailures = bulkResponse.hasFailures();System.out.println("批量操作是否失败:" + hasFailures);BulkItemResponse[] items = bulkResponse.getItems();for (BulkItemResponse item : items) {System.out.println(item.status());}// 异步操作/*restHighLevelClient.bulkAsync(request, RequestOptions.DEFAULT, new ActionListener<BulkResponse>() {@Overridepublic void onResponse(BulkResponse bulkItemResponses) {System.out.println("执行情况: " + bulkItemResponses);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return bulkResponse;}// 查询操作1@Overridepublic SearchResponse searchDocument1() throws IOException {String indexName = "student";SearchRequest searchRequest = new SearchRequest(indexName);BoolQueryBuilder booleanQueryBuilder = QueryBuilders.boolQuery();// 过滤出年龄在15~40岁之间的documentbooleanQueryBuilder.filter(QueryBuilders.rangeQuery("age").from(15).to(40));// bool must条件, 找出description字段中包含学生的documentbooleanQueryBuilder.must(QueryBuilders.matchQuery("description", "学生"));SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();// 执行查询条件// sourceBuilder.query(QueryBuilders.matchAllQuery());sourceBuilder.query(booleanQueryBuilder);MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "tom");sourceBuilder.query(matchQueryBuilder);//聚合年龄分布TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age");sourceBuilder.aggregation(ageAgg);//聚合平均年龄AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("ageAvg").field("age");sourceBuilder.aggregation(balanceAvg);// 分页查询sourceBuilder.from(0);sourceBuilder.size(5);// 排序sourceBuilder.sort("age", SortOrder.DESC);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));searchRequest.source(sourceBuilder);// 同步的方式发送请求SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {String hitString = hit.getSourceAsString();System.out.println(hitString);}// 异步方式发送请求/*restHighLevelClient.searchAsync(searchRequest, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {@Overridepublic void onResponse(SearchResponse searchResponse) {System.out.println("执行情况: " + searchResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return searchResponse;}// 查询操作2@Overridepublic SearchResponse searchDocument2() throws IOException {String indexName = "student";SearchRequest searchRequest = new SearchRequest(indexName);//构建搜索条件SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()// 在student索引的description和name字段中都查询“tom”.query(QueryBuilders.multiMatchQuery("tom", "description", "name"))// matchQuery是模糊查询,会对key进行分词// searchSourceBuilder.query(QueryBuilders.matchQuery(key,value));// termQuery是精准查询// searchSourceBuilder.query(QueryBuilders.termQuery(key,value));.sort(SortBuilders.fieldSort("age").order(SortOrder.DESC))// 一个可选项,用于控制允许搜索的时间// searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));// 指定从哪条开始查询.from(0)// 需要查出的总记录条数.size(10);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {String hitString = hit.getSourceAsString();System.out.println(hitString);}// 异步方式发送请求/*restHighLevelClient.searchAsync(searchRequest, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {@Overridepublic void onResponse(SearchResponse searchResponse) {System.out.println("执行情况: " + searchResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return searchResponse;}// 高亮查询@Overridepublic SearchResponse searchDocument3() throws IOException {String indexName = "student";SearchRequest searchRequest = new SearchRequest(indexName);// 高亮HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("name");highlightBuilder.field("description");highlightBuilder.requireFieldMatch(false);highlightBuilder.preTags("<span style='color:red'>");highlightBuilder.postTags("</span>");// 构建搜索条件SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.multiMatchQuery("tom", "description", "name")).sort(SortBuilders.fieldSort("age").order(SortOrder.DESC))// 指定从哪条开始查询.from(0)// 需要查出的总记录条数.size(10)//高亮.highlighter(highlightBuilder);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {String hitString = hit.getSourceAsString();System.out.println(hitString);// 处理高亮显示的结果HighlightField titleField = hit.getHighlightFields().get("name");if (titleField != null) {// 新建一个对象,把该属性的值重新覆盖System.out.println(titleField.getFragments()[0].toString());}HighlightField contentField = hit.getHighlightFields().get("description");if (contentField != null) {System.out.println(contentField.getFragments()[0].toString());}}// 异步方式发送请求/*restHighLevelClient.searchAsync(searchRequest, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {@Overridepublic void onResponse(SearchResponse searchResponse) {System.out.println("执行情况: " + searchResponse);}@Overridepublic void onFailure(Exception e) {System.out.println("执行失败的原因:" + e.getMessage());}});*/return searchResponse;}
}

1.6 测试类

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 新建索引@Testvoid createIndex() throws IOException {CreateIndexResponse createIndexResponse = iRestHighLevelClientService.createIndex();System.out.println("新建的索引是:" + createIndexResponse.index());}// 删除索引@Testvoid deleteIndex() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.deleteIndex();System.out.println("删除索引是否成功:" + acknowledgedResponse.isAcknowledged());}// 查看索引是否存在@Testvoid existIndex() throws IOException {Boolean aBoolean = iRestHighLevelClientService.existIndex();System.out.println("索引是否存在:" + aBoolean);}// 更新索引的settings配置@Testvoid updateIndexSettings() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.updateIndexSettings();System.out.println("是否更新settings配置成功:" + acknowledgedResponse.isAcknowledged());}// 更新索引的mapping配置@Testvoid updateIndexMapping() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.updateIndexMapping();System.out.println("是否更新mapping配置成功:" + acknowledgedResponse.isAcknowledged());}// 新增文档@Testvoid addDocument() throws IOException {IndexResponse indexResponse = iRestHighLevelClientService.addDocument();System.out.println("新增文档是否成功:" + indexResponse.status());}// 修改文档@Testvoid addDocumentByCon() throws IOException {UpdateResponse updateResponse = iRestHighLevelClientService.updateDocument();System.out.println("修改文档是否成功:" + updateResponse.status());}// 根据id删除文档@Testvoid deleteDocumentById() throws IOException {DeleteResponse deleteResponse = iRestHighLevelClientService.deleteDocumentById();System.out.println("删除文档是否成功:" + deleteResponse.status());}// 根据条件删除文档@Testvoid deleteDocumentByCon() throws IOException {BulkByScrollResponse bulkByScrollResponse = iRestHighLevelClientService.deleteDocumentByCon();System.out.println("删除文档是否成功:" + bulkByScrollResponse.getDeleted());}// 批量操作文档@Testvoid bulkDocument() throws IOException {BulkResponse bulkItemResponses = iRestHighLevelClientService.bulkDocument();System.out.println("批量操作文档是否成功:" + bulkItemResponses.status());}// 查询操作1@Testvoid searchDocument1() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument1();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}// 查询操作2@Testvoid searchDocument2() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument2();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}// 高亮查询@Testvoid searchDocument3() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument3();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}
}

1.7 启动类

package com.example.springbootelasticsearch1;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootElasticsearch1Application {public static void main(String[] args) {SpringApplication.run(SpringBootElasticsearch1Application.class, args);}}

1.8 测试

1.8.1创建索引

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 新建索引@Testvoid createIndex() throws IOException {CreateIndexResponse createIndexResponse = iRestHighLevelClientService.createIndex();System.out.println("新建的索引是:" + createIndexResponse.index());}
}

在这里插入图片描述

在这里插入图片描述

1.8.2 删除索引

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 删除索引@Testvoid deleteIndex() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.deleteIndex();System.out.println("删除索引是否成功:" + acknowledgedResponse.isAcknowledged());}
}

在这里插入图片描述

1.8.3 查看索引是否存在

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 查看索引是否存在@Testvoid existIndex() throws IOException {Boolean aBoolean = iRestHighLevelClientService.existIndex();System.out.println("索引是否存在:" + aBoolean);}
}

在这里插入图片描述

我们再次新建索引:

在这里插入图片描述

1.8.4 更新索引的settings配置

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 更新索引的settings配置@Testvoid updateIndexSettings() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.updateIndexSettings();System.out.println("是否更新settings配置成功:" + acknowledgedResponse.isAcknowledged());}
}

在这里插入图片描述

1.8.5 更新索引的mapping配置

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 更新索引的mapping配置@Testvoid updateIndexMapping() throws IOException {AcknowledgedResponse acknowledgedResponse = iRestHighLevelClientService.updateIndexMapping();System.out.println("是否更新mapping配置成功:" + acknowledgedResponse.isAcknowledged());}
}

在这里插入图片描述

在这里插入图片描述

1.8.6 新增文档

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.index.IndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 新增文档@Testvoid addDocument() throws IOException {IndexResponse indexResponse = iRestHighLevelClientService.addDocument();System.out.println("新增文档是否成功:" + indexResponse.status());}
}

在这里插入图片描述

在这里插入图片描述

1.8.7 修改文档

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.update.UpdateResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 修改文档@Testvoid addDocumentByCon() throws IOException {UpdateResponse updateResponse = iRestHighLevelClientService.updateDocument();System.out.println("修改文档是否成功:" + updateResponse.status());}
}

在这里插入图片描述

在这里插入图片描述

1.8.8 根据id删除文档

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.delete.DeleteResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 根据id删除文档@Testvoid deleteDocumentById() throws IOException {DeleteResponse deleteResponse = iRestHighLevelClientService.deleteDocumentById();System.out.println("删除文档是否成功:" + deleteResponse.status());}
}

在这里插入图片描述

在这里插入图片描述

1.8.9 根据条件删除文档

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 根据条件删除文档@Testvoid deleteDocumentByCon() throws IOException {BulkByScrollResponse bulkByScrollResponse = iRestHighLevelClientService.deleteDocumentByCon();System.out.println("删除文档是否成功:" + bulkByScrollResponse.getDeleted());}
}

新增一条文档,然后再进行测试:

在这里插入图片描述

1.8.10 批量操作文档

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.bulk.BulkResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 批量操作文档@Testvoid bulkDocument() throws IOException {BulkResponse bulkItemResponses = iRestHighLevelClientService.bulkDocument();System.out.println("批量操作文档是否成功:" + bulkItemResponses.status());}
}

在这里插入图片描述

1.8.11 查询操作1

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.search.SearchResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 查询操作1@Testvoid searchDocument1() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument1();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}
}

在这里插入图片描述

1.8.12 查询操作2

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.search.SearchResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 查询操作2@Testvoid searchDocument2() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument2();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}
}

在这里插入图片描述

1.8.13 高亮查询

package com.example.springbootelasticsearch1;import com.example.springbootelasticsearch1.service.IRestHighLevelClientService;
import org.elasticsearch.action.search.SearchResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class SpringBootElasticsearch1ApplicationTests {@Autowiredprivate IRestHighLevelClientService iRestHighLevelClientService;// 高亮查询@Testvoid searchDocument3() throws IOException {SearchResponse searchResponse = iRestHighLevelClientService.searchDocument3();System.out.println("查询数据的总数:" + searchResponse.getHits().getHits().length);System.out.println("符合条件的文档最大得分: " + searchResponse.getHits().getMaxScore());}
}

在这里插入图片描述

1.9 自定义查询

  • matchQuery:词条匹配,先分词然后在调用termQuery进行匹配

  • termQuery:词条匹配,不分词

  • wildcardQuery:通配符匹配

  • fuzzyQuery:模糊匹配

  • rangeQuery:范围匹配

  • booleanQuery:布尔查询

match query (词条匹配,先分词然后在调用termQuery进行匹配)

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "小米手机"));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

termQuery (词条匹配,不分词)

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("title", "小米"));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

fuzzyQuery (模糊匹配)

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.fuzzyQuery("title", "小米"));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

booleanQuery (布尔查询)

BooleanClause用于表示布尔查询子句关系的类,包括:BooleanClause.Occur.MUST

BooleanClause.Occur.MUST_NOTBooleanClause.Occur.SHOULD

必须包含,不能包含,可以包含三种。

有以下6种组合:

1.MUSTMUST:交集。

2.MUSTMUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。

3.SHOULDMUST_NOT:连用时,功能同MUST和MUST_NOT。

4.SHOULDMUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。

5.SHOULD与SHOULD:并集。

6.MUST_NOTMUST_NOT:无意义,检索无结果。

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("title", "手机")).must(QueryBuilders.termQuery("brand", "小米")));searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

RangeQuery 范围查找

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.rangeQuery("price").from(3000).to(4000));
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

wildcardQuery 通配符匹配

String indexName = "student";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.wildcardQuery("title", "%小米%"));
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

2、spring-boot-starter-data-elasticsearch方式

使用ElasticsearchRepository进行操作,ElasticSearchRepository方式主要通过注解和对接口实现的方式

来实现ES的操作,我们在实体类上通过注解配置ES索引的映射关系后,当实现了ElasticSearchRepository接口的

类第一次操作ES进行插入文档的时候,ES会自动生成所需要的一切。但是该种方式无法实现高亮查询,想要实现

高亮查询只能使用RestHighLevelClient

想要使用高版本,在创建实体的@Document属性中不可以加入type = "_doc"

2.1 导入依赖

<?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.5.6</version><relativePath/></parent><groupId>com.example</groupId><artifactId>spring-boot-elasticsearch2</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-elasticsearch2</name><description>spring-boot-elasticsearch2</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></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-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.2 配置类和配置文件

package com.example.springbootelasticsearch2.config;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;@Configuration
public class EsConfig extends AbstractElasticsearchConfiguration {@Value("${elasticsearch.hostname}")private String hostname;@Value("${elasticsearch.port}")private int port;@Override@Beanpublic RestHighLevelClient elasticsearchClient() {final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo(hostname + ":" + port).build();return RestClients.create(clientConfiguration).rest();}
}
# es配置
elasticsearch.hostname=127.0.0.1
elasticsearch.port=9200# 默认配置,在本地启动的时候可以不配置
# spring.elasticsearch.rest.uris=http://127.0.0.1:9200

2.3 创建实体类

package com.example.springbootelasticsearch2.entity;import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;import java.util.Date;@Document(indexName = "book", createIndex = true)
public class Book {@Id@Field(type = FieldType.Text)private String id;@Field(type = FieldType.Text, analyzer = "ik_max_word")private String title;@Field(type = FieldType.Text, analyzer = "ik_max_word")private String author;@Field(type = FieldType.Double)private Double price;@Field(type = FieldType.Date, format = DateFormat.basic_date_time)private Date createTime;@Field(type = FieldType.Date, format = DateFormat.basic_date_time)private Date updateTime;public Book() {}public Book(String id, String title, String author, Double price, Date createTime, Date updateTime) {this.id = id;this.title = title;this.author = author;this.price = price;this.createTime = createTime;this.updateTime = updateTime;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}
}

createIndex = true:无需手动创建Book索引,SpringBoot启动自动创建。

@Document: 作用在类,标记实体类为文档对象,一般有四个属性:

  • indexName:对应索引库名称
  • shards:分片数量,默认5
  • replicas:副本数量,默认1
  • type:用来指定索引类型,7.x以后的版本移除了

@Id:作用在成员变量,标记一个字段作为id主键,用来将对象中id和ES中_id映射。

@Field:作用在成员变量,标记为文档的字段,并指定字段映射属性:

  • type:字段类型,取值是枚举:FieldType,具体的数据类型有:text、keyword、long、short、

    date、integer、object、byte、double、float、half_float、scaled_float

  • index:是否索引,布尔类型,默认是true

  • store:是否存储,布尔类型,默认是false

  • analyzer:分词器名称,用来指定使用哪种分词器

  • format:时间格式

  • fielddata:聚类的时候使用

@Transient:默认情况下,存储或检索文档时,所有字段都映射到文档,此注释不包括该字段。

2.4 创建Repository仓库

package com.example.springbootelasticsearch2.repository;import com.example.springbootelasticsearch2.entity.Book;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import java.util.List;public interface ESBookRepository extends ElasticsearchRepository<Book, String> {List<Book> findByTitleOrAuthor(String title, String author);@Highlight(fields = {@HighlightField(name = "title"),@HighlightField(name = "author")})@Query("{\"match\":{\"title\":\"?0\"}}")SearchHits<Book> find(String keyword);
}

2.5 Service

package com.example.springbootelasticsearch2.service;public interface BookService {
}
package com.example.springbootelasticsearch2.service.impl;import com.example.springbootelasticsearch2.repository.ESBookRepository;
import com.example.springbootelasticsearch2.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;@Service
public class BookServiceImpl implements BookService {@Autowiredprivate ESBookRepository esBookRepository;@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;
}

2.6 测试类

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.jupiter.api.Test;
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.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 创建索引*/@Testpublic void testCreateIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);Document mapping = indexOperations.createMapping();indexOperations.putMapping(mapping);}/*** 删除索引*/@Testpublic void testDeleteIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);indexOperations.delete();}/*** 索引是否存在*/@Testpublic void testExistsIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);indexOperations.exists();}/*** 新增文档*/@Testvoid addDocument() {Book book1 = new Book("1", "《西游记》", "吴承恩", 49.9, new Date(), new Date());esBookRepository.save(book1);Book book2 = new Book("2", "《红楼梦》", "曹雪芹", 59.9, new Date(), new Date());esBookRepository.save(book2);Book book3 = new Book("3", "《三国演义》", "罗贯中", 39.9, new Date(), new Date());esBookRepository.save(book3);Book book4 = new Book("4", "《水浒传》", "施耐庵", 69.9, new Date(), new Date());esBookRepository.save(book4);}/*** 一次新增多条文档*/@Testpublic void addManyDocument() {List<Book> books = new ArrayList<Book>();Book book1 = new Book("1", "《西游记》", "吴承恩", 49.9, new Date(), new Date());Book book2 = new Book("2", "《红楼梦》", "曹雪芹", 59.9, new Date(), new Date());Book book3 = new Book("3", "《三国演义》", "罗贯中", 39.9, new Date(), new Date());Book book4 = new Book("4", "《水浒传》", "施耐庵", 69.9, new Date(), new Date());books.add(book1);books.add(book2);books.add(book3);books.add(book4);esBookRepository.saveAll(books);}/*** 判断某id的文档是否存在*/@Testvoid documentExist() {boolean exists = esBookRepository.existsById("2");System.out.println(exists);}/*** 修改文档*/@Testvoid updateDocument() {Book book = new Book("1", "《西游记》", "吴承恩", 149.9, new Date(), new Date());esBookRepository.save(book);}/*** 删除文档*/@Testvoid deleteDocument() {esBookRepository.deleteById("1");}/*** 删除所有文档*/@Testvoid deleteAllDocument() {esBookRepository.deleteAll();}/*** 根据id查询文档*/@Testvoid queryDocumentByID() {Optional<Book> book = esBookRepository.findById("1");System.out.println(book.get());}/*** 查询所有文档*/@Testvoid queryAllDocument() {Iterable<Book> all = esBookRepository.findAll();all.forEach(System.out::println);}/*** 排序文档*/@Testvoid sortAllDocument() {Iterable<Book> all = esBookRepository.findAll(Sort.by(Sort.Order.asc("price")));all.forEach(System.out::println);}// 分页@Testvoid pageDocument() {// SpringBoot2.5.6已经移除了ElasticsearchRepository里的search()方法,只剩了一些特别基础的增删改查,基本上是不能用的。// 官方明显是想让开发者用ElasticsearchRestTemplate去做。MatchAllQueryBuilder matchQueryBuilder = QueryBuilders.matchAllQuery();NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);nativeSearchQuery.setPageable(PageRequest.of(2, 1));SearchHits<Book> search = elasticsearchRestTemplate.search(nativeSearchQuery, Book.class);for (SearchHit<Book> hit : search.getSearchHits()) {System.out.println(hit.getContent().getTitle());}}// 自定义查询@Testvoid query1() {List<Book> book = esBookRepository.findByTitleOrAuthor("《红楼梦》", "曹雪芹");book.forEach(System.out::println);}// 自定义json规则查询@Testvoid query2() {SearchHits<Book> book = esBookRepository.find("《红楼梦》");// SearchHit{id='2', score=3.1789374, sortValues=[], content=com.example.springbootelasticsearch2.entity.Book@48cb2d73,// highlightFields={title=[《<em>红楼梦</em>》]}}book.forEach(System.out::println);}}

2.7 启动类

package com.example.springbootelasticsearch2;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootElasticsearch2Application {public static void main(String[] args) {SpringApplication.run(SpringBootElasticsearch2Application.class, args);}}

2.8 测试

2.8.1 新建索引

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 创建索引*/@Testpublic void testCreateIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);Document mapping = indexOperations.createMapping();indexOperations.putMapping(mapping);}
}

在这里插入图片描述

在这里插入图片描述

2.8.2 删除索引

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 删除索引*/@Testpublic void testDeleteIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);indexOperations.delete();}
}

在这里插入图片描述

2.8.3 索引是否存在

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 索引是否存在*/@Testpublic void testExistsIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Book.class);indexOperations.exists();}
}

在这里插入图片描述

2.8.4 新增文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;import java.util.Date;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 新增文档*/@Testvoid addDocument() {Book book1 = new Book("1", "《西游记》", "吴承恩", 49.9, new Date(), new Date());esBookRepository.save(book1);Book book2 = new Book("2", "《红楼梦》", "曹雪芹", 59.9, new Date(), new Date());esBookRepository.save(book2);Book book3 = new Book("3", "《三国演义》", "罗贯中", 39.9, new Date(), new Date());esBookRepository.save(book3);Book book4 = new Book("4", "《水浒传》", "施耐庵", 69.9, new Date(), new Date());esBookRepository.save(book4);}
}

在这里插入图片描述

在这里插入图片描述

2.8.5 判断某id的文档是否存在

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 判断某id的文档是否存在*/@Testvoid documentExist() {boolean exists = esBookRepository.existsById("2");System.out.println(exists);}}

在这里插入图片描述

2.8.6 修改文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.util.Date;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 修改文档*/@Testvoid updateDocument() {Book book = new Book("1", "《西游记》", "吴承恩", 149.9, new Date(), new Date());esBookRepository.save(book);}
}

在这里插入图片描述

在这里插入图片描述

2.8.7 删除文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 删除文档*/@Testvoid deleteDocument() {esBookRepository.deleteById("1");}
}

在这里插入图片描述

2.8.8 刪除所有文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 删除所有文档*/@Testvoid deleteAllDocument() {esBookRepository.deleteAll();}}

在这里插入图片描述

在这里插入图片描述

2.8.9 一次新增多条文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.util.ArrayList;
import java.util.Date;
import java.util.List;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 一次新增多条文档*/@Testpublic void addManyDocument() {List<Book> books = new ArrayList<Book>();Book book1 = new Book("1", "《西游记》", "吴承恩", 49.9, new Date(), new Date());Book book2 = new Book("2", "《红楼梦》", "曹雪芹", 59.9, new Date(), new Date());Book book3 = new Book("3", "《三国演义》", "罗贯中", 39.9, new Date(), new Date());Book book4 = new Book("4", "《水浒传》", "施耐庵", 69.9, new Date(), new Date());books.add(book1);books.add(book2);books.add(book3);books.add(book4);esBookRepository.saveAll(books);}}

在这里插入图片描述

在这里插入图片描述

2.8.10 根据id查询文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.util.Optional;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 根据id查询文档*/@Testvoid queryDocumentByID() {Optional<Book> book = esBookRepository.findById("2");System.out.println(book.get());}
}

在这里插入图片描述

2.8.11 查询所有文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.util.Optional;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 查询所有文档*/@Testvoid queryAllDocument() {Iterable<Book> all = esBookRepository.findAll();all.forEach(System.out::println);}
}

在这里插入图片描述

2.8.12 排序文档

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;/*** 排序文档*/@Testvoid sortAllDocument() {Iterable<Book> all = esBookRepository.findAll(Sort.by(Sort.Order.asc("price")));all.forEach(System.out::println);}}

在这里插入图片描述

2.8.13 分页

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;// 分页@Testvoid pageDocument() {// SpringBoot2.5.6已经移除了ElasticsearchRepository里的search()方法,只剩了一些特别基础的增删改查,基本上是不能用的。// 官方明显是想让开发者用ElasticsearchRestTemplate去做。MatchAllQueryBuilder matchQueryBuilder = QueryBuilders.matchAllQuery();NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchQueryBuilder);nativeSearchQuery.setPageable(PageRequest.of(2, 1));SearchHits<Book> search = elasticsearchRestTemplate.search(nativeSearchQuery, Book.class);for (SearchHit<Book> hit : search.getSearchHits()) {System.out.println(hit.getContent().getTitle());}}}

在这里插入图片描述

2.8.14 自定义查询

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.util.List;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;// 自定义查询@Testvoid query1() {List<Book> book = esBookRepository.findByTitleOrAuthor("《红楼梦》", "曹雪芹");book.forEach(System.out::println);}}

在这里插入图片描述

2.8.15 自定义json规则查询

package com.example.springbootelasticsearch2;import com.example.springbootelasticsearch2.entity.Book;
import com.example.springbootelasticsearch2.repository.ESBookRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;@SpringBootTest
class SpringBootElasticsearch2ApplicationTests {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@Autowiredprivate ESBookRepository esBookRepository;// 自定义json规则查询@Testvoid query2() {SearchHits<Book> book = esBookRepository.find("《红楼梦》");// SearchHit{id='2', score=3.1789374, sortValues=[], content=com.example.springbootelasticsearch2.entity.Book@48cb2d73, // highlightFields={title=[《<em>红楼梦</em>》]}}book.forEach(System.out::println);}}

在这里插入图片描述

2.9 自定义查询规则

KeywordSampleElasticsearch Query String
AndfindByNameAndPrice{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
OrfindByNameOrPrice{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
IsfindByName{"bool" : {"must" : {"field" : {"name" : "?"}}}}
NotfindByNameNot{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
BetweenfindByPriceBetween{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqualfindByPriceLessThan{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqualfindByPriceGreaterThan{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
BeforefindByPriceBefore{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
AfterfindByPriceAfter{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
LikefindByNameLike{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWithfindByNameStartingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWithfindByNameEndingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/ContainingfindByNameContaining{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
InfindByNameIn (Collection<String>names){"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotInfindByNameNotIn (Collection<String>names){"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{"bool" : {"must" : {"field" : {"available" : true}}}}
FalsefindByAvailableFalse{"bool" : {"must" : {"field" : {"available" : false}}}}
OrderByfindByAvailable TrueOrderByNameDesc{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

我们只要按照上面的定义在接口中定义相应的方法,无须写实现就可实现我们想要的功能。

系统提供的查询方法中findBy是一个固定写法,像上面我们定义的方法findByTitle,其中Title是我们实体

类中的属性名,这个必须对应上。findByTitle是下面这样定义的:

{"bool" : {"must" : {"field" : {"title" : "?"}}}}

假如我们现在有个需求需要按照作者查询书籍,我们可以在BookRepository中定义一个方法,如下:

// 根据作者查询书籍
List<User> findByAuthor(String author);

那么我们可以使用该方法:

@Test
public void testFindBookByAuthor(){List<Book> bookList = bookRepository.findByAuthor("曹雪芹");bookList.forEach(System.out::println);
}

其实就是框架底层直接使用下面的命令帮我们实现的查询:

GET /book/_search
{"query": {"bool": {"must": [{"term": {"author":"曹雪芹"}}]}}
}

在这里插入图片描述

ElasticSearchRepository实现不了高亮查询,想要实现高亮查询还是需要使用RestHighLevelClient方式。

3、transport方式(7.x开始弃用)

使用TransportClient进行操作

3.1 导入依赖

<?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.5.6</version><relativePath/></parent><groupId>com.example</groupId><artifactId>spring-boot-elasticsearch3</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-elasticsearch3</name><description>spring-boot-elasticsearch3</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>7.12.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.58</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3.2 配置文件

elasticsearch.cluster-name = elasticsearch
elasticsearch.ip = 127.0.0.1
elasticsearch.port = 9300
elasticsearch.pool = 5

3.3 创建配置类

package com.example.springbootelasticsearch3.config;import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.net.InetAddress;/*** @author zhangshixing* @date 2021年11月11日 12:28*/
@Slf4j
@Configuration
public class ElasticSearchConfig {@Value("${elasticsearch.ip}")private String hostName;/*** 端口*/@Value("${elasticsearch.port}")private String port;/*** 集群名称*/@Value("${elasticsearch.cluster-name}")private String clusterName;/*** 连接池*/@Value("${elasticsearch.pool}")private String poolSize;/*** Bean name default  函数名字** @return*/@Bean(name = "transportClient")public TransportClient transportClient() {log.info("Elasticsearch初始化开始。。。。。");TransportClient transportClient = null;try {// 配置信息Settings esSetting = Settings.builder()//集群名字.put("cluster.name", clusterName)//增加嗅探机制,找到ES集群.put("client.transport.sniff", true)//增加线程池个数,暂时设为5.put("thread_pool.search.size", Integer.parseInt(poolSize)).build();//配置信息Settings自定义transportClient = new PreBuiltTransportClient(esSetting);TransportAddress transportAddress = new TransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port));transportClient.addTransportAddresses(transportAddress);} catch (Exception e) {log.error("elasticsearch TransportClient create error!!", e);}return transportClient;}
}

3.4 创建工具类

package com.example.springbootelasticsearch3.utils;import java.util.List;
import java.util.Map;/*** @author zhangshixing* @date 2021年11月11日 12:42*/
public class EsPage {/*** 当前页*/private int currentPage;/*** 每页显示多少条*/private int pageSize;/*** 总记录数*/private int recordCount;/*** 本页的数据列表*/private List<Map<String, Object>> recordList;/*** 总页数*/private int pageCount;/*** 页码列表的开始索引(包含)*/private int beginPageIndex;/*** 页码列表的结束索引(包含)*/private int endPageIndex;/*** 只接受前4个必要的属性,会自动的计算出其他3个属性的值** @param currentPage* @param pageSize* @param recordCount* @param recordList*/public EsPage(int currentPage, int pageSize, int recordCount, List<Map<String, Object>> recordList) {this.currentPage = currentPage;this.pageSize = pageSize;this.recordCount = recordCount;this.recordList = recordList;// 计算总页码pageCount = (recordCount + pageSize - 1) / pageSize;// 计算 beginPageIndex 和 endPageIndex// >> 总页数不多于10页,则全部显示if (pageCount <= 10) {beginPageIndex = 1;endPageIndex = pageCount;}// >> 总页数多于10页,则显示当前页附近的共10个页码else {// 当前页附近的共10个页码(前4个 + 当前页 + 后5个)beginPageIndex = currentPage - 4;endPageIndex = currentPage + 5;// 当前面的页码不足4个时,则显示前10个页码if (beginPageIndex < 1) {beginPageIndex = 1;endPageIndex = 10;}// 当后面的页码不足5个时,则显示后10个页码if (endPageIndex > pageCount) {endPageIndex = pageCount;beginPageIndex = pageCount - 10 + 1;}}}public int getCurrentPage() {return currentPage;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getRecordCount() {return recordCount;}public void setRecordCount(int recordCount) {this.recordCount = recordCount;}public List<Map<String, Object>> getRecordList() {return recordList;}public void setRecordList(List<Map<String, Object>> recordList) {this.recordList = recordList;}public int getPageCount() {return pageCount;}public void setPageCount(int pageCount) {this.pageCount = pageCount;}public int getBeginPageIndex() {return beginPageIndex;}public void setBeginPageIndex(int beginPageIndex) {this.beginPageIndex = beginPageIndex;}public int getEndPageIndex() {return endPageIndex;}public void setEndPageIndex(int endPageIndex) {this.endPageIndex = endPageIndex;}}
package com.example.springbootelasticsearch3.utils;import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;/*** @author zhangshixing* @date 2021年11月11日 12:39*/
@Component
@Slf4j
public class ElasticsearchUtil {@Autowiredprivate TransportClient transportClient;private static TransportClient client;/*** @PostContruct是spring框架的注解 spring容器初始化的时候执行该方法*/@PostConstructpublic void init() {client = this.transportClient;}/*** 创建索引** @param index* @return*/public static boolean createIndex(String index) {if (!isIndexExist(index)) {log.info("Index is not exits!");}CreateIndexResponse indexResponse = client.admin().indices().prepareCreate(index).execute().actionGet();log.info("执行建立成功?" + indexResponse.isAcknowledged());return indexResponse.isAcknowledged();}/*** 删除索引** @param index* @return*/public static boolean deleteIndex(String index) {if (!isIndexExist(index)) {log.info("Index is not exits!");}AcknowledgedResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();if (dResponse.isAcknowledged()) {log.info("delete index " + index + "  successfully!");} else {log.info("Fail to delete index " + index);}return dResponse.isAcknowledged();}/*** 判断索引是否存在** @param index* @return*/public static boolean isIndexExist(String index) {IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();if (inExistsResponse.isExists()) {log.info("Index [" + index + "] is exist!");} else {log.info("Index [" + index + "] is not exist!");}return inExistsResponse.isExists();}/*** 数据添加,正定ID** @param jsonObject 要增加的数据* @param index      索引,类似数据库* @param type       类型,类似表* @param id         数据ID* @return*/public static String addData(JSONObject jsonObject, String index, String type, String id) {IndexResponse response = client.prepareIndex(index, type, id).setSource(jsonObject).get();log.info("addData response status:{},id:{}", response.status().getStatus(), response.getId());return response.getId();}/*** 数据添加** @param jsonObject 要增加的数据* @param index      索引,类似数据库* @param type       类型,类似表* @return*/public static String addData(JSONObject jsonObject, String index, String type) {return addData(jsonObject, index, type, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());}/*** 通过ID删除数据** @param index 索引,类似数据库* @param type  类型,类似表* @param id    数据ID*/public static void deleteDataById(String index, String type, String id) {DeleteResponse response = client.prepareDelete(index, type, id).execute().actionGet();log.info("deleteDataById response status:{},id:{}", response.status().getStatus(), response.getId());}/*** 通过ID 更新数据** @param jsonObject 要增加的数据* @param index      索引,类似数据库* @param type       类型,类似表* @param id         数据ID* @return*/public static void updateDataById(JSONObject jsonObject, String index, String type, String id) {UpdateRequest updateRequest = new UpdateRequest();updateRequest.index(index).type(type).id(id).doc(jsonObject);client.update(updateRequest);}/*** 通过ID获取数据** @param index  索引,类似数据库* @param type   类型,类似表* @param id     数据ID* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)* @return*/public static Map<String, Object> searchDataById(String index, String type, String id, String fields) {GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id);if (StringUtils.isNotEmpty(fields)) {getRequestBuilder.setFetchSource(fields.split(","), null);}GetResponse getResponse = getRequestBuilder.execute().actionGet();return getResponse.getSource();}/*** 使用分词查询,并分页** @param index          索引名称* @param type           类型名称,可传入多个type逗号分隔* @param startPage      当前页* @param pageSize       每页显示条数* @param query          查询条件* @param fields         需要显示的字段,逗号分隔(缺省为全部字段)* @param sortField      排序字段* @param highlightField 高亮字段* @return*/public static EsPage searchDataPage(String index, String type, int startPage, int pageSize, QueryBuilder query, String fields, String sortField, String highlightField) {SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);if (StringUtils.isNotEmpty(type)) {searchRequestBuilder.setTypes(type.split(","));}searchRequestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);// 需要显示的字段,逗号分隔(缺省为全部字段)if (StringUtils.isNotEmpty(fields)) {searchRequestBuilder.setFetchSource(fields.split(","), null);}//排序字段if (StringUtils.isNotEmpty(sortField)) {searchRequestBuilder.addSort(sortField, SortOrder.DESC);}// 高亮(xxx=111,aaa=222)if (StringUtils.isNotEmpty(highlightField)) {HighlightBuilder highlightBuilder = new HighlightBuilder();//highlightBuilder.preTags("<span style='color:red' >");//设置前缀//highlightBuilder.postTags("</span>");//设置后缀// 设置高亮字段highlightBuilder.field(highlightField);searchRequestBuilder.highlighter(highlightBuilder);}//searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());searchRequestBuilder.setQuery(query);// 分页应用searchRequestBuilder.setFrom(startPage).setSize(pageSize);// 设置是否按查询匹配度排序searchRequestBuilder.setExplain(true);//打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询log.info("\n{}", searchRequestBuilder);// 执行搜索,返回搜索响应信息SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();TotalHits totalHits = searchResponse.getHits().getTotalHits();long length = searchResponse.getHits().getHits().length;log.debug("共查询到[{}]条数据,处理数据条数[{}]", totalHits.value, length);if (searchResponse.status().getStatus() == 200) {// 解析对象List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightField);return new EsPage(startPage, pageSize, (int) totalHits.value, sourceList);}return null;}/*** 使用分词查询** @param index          索引名称* @param type           类型名称,可传入多个type逗号分隔* @param query          查询条件* @param size           文档大小限制* @param fields         需要显示的字段,逗号分隔(缺省为全部字段)* @param sortField      排序字段* @param highlightField 高亮字段* @return*/public static List<Map<String, Object>> searchListData(String index, String type, QueryBuilder query, Integer size, String fields, String sortField, String highlightField) {SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);if (StringUtils.isNotEmpty(type)) {searchRequestBuilder.setTypes(type.split(","));}if (StringUtils.isNotEmpty(highlightField)) {HighlightBuilder highlightBuilder = new HighlightBuilder();// 设置高亮字段highlightBuilder.field(highlightField);searchRequestBuilder.highlighter(highlightBuilder);}searchRequestBuilder.setQuery(query);if (StringUtils.isNotEmpty(fields)) {searchRequestBuilder.setFetchSource(fields.split(","), null);}searchRequestBuilder.setFetchSource(true);if (StringUtils.isNotEmpty(sortField)) {searchRequestBuilder.addSort(sortField, SortOrder.DESC);}if (size != null && size > 0) {searchRequestBuilder.setSize(size);}//打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询log.info("\n{}", searchRequestBuilder);SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();TotalHits totalHits = searchResponse.getHits().getTotalHits();long length = searchResponse.getHits().getHits().length;log.info("共查询到[{}]条数据,处理数据条数[{}]", totalHits.value, length);if (searchResponse.status().getStatus() == 200) {// 解析对象return setSearchResponse(searchResponse, highlightField);}return null;}/*** 高亮结果集 特殊处理** @param searchResponse* @param highlightField*/private static List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();StringBuffer stringBuffer = new StringBuffer();for (SearchHit searchHit : searchResponse.getHits().getHits()) {searchHit.getSourceAsMap().put("id", searchHit.getId());if (StringUtils.isNotEmpty(highlightField)) {System.out.println("遍历 高亮结果集,覆盖 正常结果集" + searchHit.getSourceAsMap());Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments();if (text != null) {for (Text str : text) {stringBuffer.append(str.string());}//遍历 高亮结果集,覆盖 正常结果集searchHit.getSourceAsMap().put(highlightField, stringBuffer.toString());}}sourceList.add(searchHit.getSourceAsMap());}return sourceList;}
}

3.5 启动类

package com.example.springbootelasticsearch3;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootElasticsearch3Application {public static void main(String[] args) {SpringApplication.run(SpringBootElasticsearch3Application.class, args);}}

3.6 测试类

package com.example.springbootelasticsearch3;import com.alibaba.fastjson.JSONObject;
import com.example.springbootelasticsearch3.utils.ElasticsearchUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;/*** @author zhangshixing* @date 2021年11月11日 12:43*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class GoodsResiportyTest {/*** 类型*/private String esType = "external";/*** 索引*/private String indexName = "test_index";/*** 创建索引*/@Testpublic void createIndex() {if (!ElasticsearchUtil.isIndexExist(indexName)) {ElasticsearchUtil.createIndex(indexName);} else {System.out.print("索引已经存在");}System.out.print("索引创建成功");}/*** 删除索引*/@Testpublic void deleteIndex() {if (!ElasticsearchUtil.isIndexExist(indexName)) {System.out.print("索引不存在");} else {ElasticsearchUtil.deleteIndex(indexName);}System.out.print("索引删除成功");}/*** 索引是否存在*/@Testpublic void cexistsIndex() {if (!ElasticsearchUtil.isIndexExist(indexName)) {System.out.print("索引不存在");} else {System.out.print("索引存在");}}/*** 指定索引插入数据*/@Testpublic void insertJson() {JSONObject jsonObject = new JSONObject();jsonObject.put("id", DateUtils.formatDate(new Date()));jsonObject.put("age", 25);jsonObject.put("name", "j-" + new Random(100).nextInt());jsonObject.put("createTime", new Date());String id = ElasticsearchUtil.addData(jsonObject, indexName, esType, jsonObject.getString("id"));}@Testpublic void delete() {String id = "12";if (StringUtils.isNotBlank(id)) {ElasticsearchUtil.deleteDataById(indexName, esType, id);System.out.print("删除id=" + id);} else {System.out.print("id为空");}}@Testpublic void queryMatchData() {BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();boolean matchPhrase = false;if (matchPhrase == Boolean.TRUE) {boolQuery.must(QueryBuilders.matchPhraseQuery("name", "j"));} else {boolQuery.must(QueryBuilders.matchQuery("name", "j"));}List<Map<String, Object>> list = ElasticsearchUtil.searchListData(indexName, esType, boolQuery, 10, null, null, null);System.out.print(JSONObject.toJSONString(list));}
}
{"size":10,"query":{"bool":{"must":[{"match":{"name":{"query":"j","operator":"OR","prefix_length":0,"max_expansions":50,"fuzzy_transpositions":true,"lenient":false,"zero_terms_query":"NONE","auto_generate_synonyms_phrase_query":true,"boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},"_source":{"includes":[],"excludes":[]}}
2022-06-23 10:59:36.190  INFO 18272 --- [           main] c.e.s.utils.ElasticsearchUtil            : 共查询到[1]条数据,处理数据条数[1]
[{"createTime":"2022-06-23T02:56:35.337Z","name":"j--1193959466","id":"Thu, 23 Jun 2022 02:56:35 GMT","age":25}]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/21327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin~Facade

概念 又称门面模式&#xff0c;为复杂系统提供简单交互接口。 角色介绍 Facade&#xff1a;外观类&#xff0c;供客户端调用&#xff0c;将请求委派给响应的子系统。SubSystem&#xff1a;子系统&#xff0c;独立的子设备或子类 UML 代码实现 class Light(val name: Strin…

STM32基础回顾

文章目录 单片机编程的原理GPIO中断EXTI外部中断定时器中断、串口中断 定时器定时器中断配置过程通用定时器输出比较功能&#xff1a;PWM波的生成定时器的输入捕获功能主从触发模式PWMI模式 定时器的编码器接口 DMA简介通信接口USART软件配置流程&#xff1a;1、仅发数据的配置…

计算两个日期相差几年几月几天,考虑闰年平年

java8以下 计算两个日期相差几年几月几天&#xff0c;考虑闰年平年 // java 计算两个日期相差几年几月几天&#xff0c;考虑闰年平年public void calculateDifference(String startDade, String endDate) {Calendar calendar1 Calendar.getInstance(); // 第一个日期&#…

深度解析线程池的文章

java 系统的运行归根到底是程序的运行&#xff0c;程序的运行归根到底是代码的执行&#xff0c;代码的执行归根到底是虚拟机的执行&#xff0c;虚拟机的执行其实就是操作系统的线程在执行&#xff0c;并且会占用一定的系统资源&#xff0c;如CPU、内存、磁盘、网络等等。所以&a…

【雕爷学编程】MicroPython动手做(31)——物联网之Easy IoT 3

1、物联网的诞生 美国计算机巨头微软(Microsoft)创办人、世界首富比尔盖茨&#xff0c;在1995年出版的《未来之路》一书中&#xff0c;提及“物物互联”。1998年麻省理工学院提出&#xff0c;当时被称作EPC系统的物联网构想。2005年11月&#xff0c;国际电信联盟发布《ITU互联网…

uniapp 中过滤获得数组中某个对象里id:1的数据

// 假设studentData是包含多个学生信息的数组 const studentData [{id: 1, name: 小明, age: 18},{id: 2, name: 小红, age: 20},{id: 3, name: 小刚, age: 19},{id: 4, name: 小李, age: 22}, ]; // 过滤获取id为1的学生信息 const result studentData.filter(item > ite…

Akuity Certified ArgoCD课程学习与认证

今天是「DevOps云学堂」与你共同进步的第 48天 第⑦期DevOps实战训练营 7月15日已开营 实践环境升级基于K8s和ArgoCD 本文主要分享&#xff0c;如何免费地参与由Akuity Academy提供的ArgoCD GitOps 培训课程并取得认证证书。 目前Akuity Academy只发布了Introduction to Contin…

Django学习笔记-默认的用户认证系统(auth)

一、Django默认的用户认证系统 Django 自带一个用户验证系统。它负责处理用户账号、组、权限和基于cookie的用户会话。 Django 验证系统处理验证和授权。简单来说&#xff0c;验证检验用户是否是他们的用户&#xff0c;授权决定已验证用户能做什么。这里的术语验证用于指代这…

使用 FastGPT 构建高质量 AI 知识库

作者&#xff1a;余金隆。FastGPT 项目作者&#xff0c;Sealos 项目前端负责人&#xff0c;前 Shopee 前端开发工程师 FastGPT 项目地址&#xff1a;https://github.com/labring/FastGPT/ 引言 自从去年 12 月 ChatGPT 发布以来&#xff0c;带动了一轮新的交互应用革命。尤其在…

GPT Prompt编写的艺术:如何提高AI模型的表现力

随着AI技术的迅速发展&#xff0c;人工智能模型变得越来越强大&#xff0c;能够协助我们完成各种任务。然而&#xff0c;如何更好地利用AI的能力仍然存在很大的探索空间。在与AI进行交互的过程中&#xff0c;我们主要依赖于Prompt&#xff0c;不管是直接与大模型交互&#xff0…

layui之layer弹出层的icon数字及效果展示

layer的icon样式 icon如果在信息提示弹出层值(type为0)可以传入0-6&#xff0c;icon与图标对应关系如下&#xff1a; 如果是加载层&#xff08;type为3&#xff09;可以传入0-2&#xff0c;icon与图标对应关系如下&#xff1a;

Java中运算符要注意的一些点

目录 1. 算术运算符 1. 1 基本四则运算符&#xff1a;加减乘除模( - * / %) 1.2. 增量运算符 - * % 2. 关系运算符 3. 逻辑运算符 3.1. 逻辑与 && 3.2. 逻辑 || 3.3. 逻辑非 ! 3.4. 短路求值 4. 位运算符 4.1. 按位与 &: 如果两个二进制位都是 …

骨传导耳机什么牌子好?盘点最受欢迎的几款骨传导耳机

骨传导耳机最近一两年越来越受欢迎&#xff0c;市场上不同形态的非入耳式耳机都有&#xff0c;从骨传导&#xff0c;夹耳式到气传导等等都有。骨传导耳机的好处有很多&#xff0c;非入耳式&#xff0c;不伤耳朵&#xff0c;佩戴更舒适更安全。但是一直以来&#xff0c;骨传导耳…

【2023年电赛】运动目标控制与自动追踪系统(E 题)最简单实现

本方案的思路是最简单的不涉及复杂算法&#xff1a;识别矩形框&#xff0c;标记矩形框&#xff0c;输出坐标和中心点&#xff0c;计算长度&#xff0c;控制舵机移动固定长度&#xff01;仅供完成基础功能参考&#xff0c;不喜勿喷&#xff01; # 实现运动目标控制与自动追踪系…

租赁类小程序定制开发|租赁管理系统源码|免押租赁系统开发

随着互联网的发展&#xff0c;小程序成为了一种重要的移动应用开发方式。租赁小程序作为其中的一种类型&#xff0c;可以为很多行业提供便利和创新。下面我们将介绍一些适合开发租赁小程序的行业。   房屋租赁行业&#xff1a;租房小程序可以帮助房东和租户快速找到合适的租赁…

Vue2 第十七节 Vue中的Ajax

1.Vue脚手架配置代理 2.vue-resource 一.Vue脚手架配置代理 1.1 使用Ajax库 -- axios ① 安装 : npm i axios ② 引入: import axios from axios ③ 使用示例 1.2 解决开发环境Ajax跨域问题 跨域&#xff1a;违背了同源策略&#xff0c;同源策略规定协议名&#xff0…

idea-常用插件汇总

idea-常用插件汇总 码云插件 这个插件是码云提供的ps-码云是国内的一款类似github的代码托管工具。 Lombok Lombok是一个通用Java类库&#xff0c;能自动插入编辑器并构建工具&#xff0c;简化Java开发。通过添加注解的方式&#xff0c;不需要为类编写getter或setter等方法…

Java源码规则引擎:jvs-rules 8月新增功能介绍

JVS-rules是JAVA语言下开发的规则引擎&#xff0c;是jvs企业级数字化解决方案中的重要配置化工具&#xff0c;核心解决业务判断的配置化&#xff0c;常见的使用场景&#xff1a;金融信贷风控判断、商品优惠折扣计算、对员工考核评分等各种变化的规则判断情景。 8月是收获的季节…

7种有效安全的网页抓取方法,如何避免被禁止?

网页抓取是一种从互联网上抓取网页内容的过程&#xff0c;但在网络抓取种相信您也经常遇到障碍&#xff1f;尤其是做跨境业务的&#xff0c;在抓取国外的网站时更有难度。但我们站在您的立场上&#xff0c;提供七种有效的方法来进行网页抓取而不被阻止&#xff0c;最大限度地降…

windows安装kafka配置SASL-PLAIN安全认证

目录 1.Windows安装zookeeper&#xff1a; 1.1下载zookeeper 1.2 解压之后如图二 1.3创建日志文件 1.4复制 “zoo_sample.cfg” 文件 1.5更改 “zoo.cfg” 配置 1.6新建zk_server_jaas.conf 1.7修改zkEnv.cmd 1.8导入相关jar 1.9以上配置就配好啦&#xff0c;接下来启…