当前位置: 首页 > news >正文

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}]

相关文章:

SpringBoot2.5.6整合Elasticsearch7.12.1

SpringBoot2.5.6整合Elasticsearch7.12.1 下面将通过SpringBoot整合Elasticseach&#xff0c;SpringBoot的版本是2.5.6&#xff0c;Elasticsearch的版本是7.12.1。 SpringBoot整合Elasticsearch主要有三种方式&#xff0c;一种是通过elasticsearch-rest-high-level-client&am…...

准大一信息安全/网络空间安全专业学习规划

如何规划&#xff1f; 学习需要一个良好的学习习惯&#xff0c;建议刚开始一定要精通一项程序语言&#xff0c;学习其他的就会一通百通。过程中是按步骤学习&#xff0c;绝不半途看见苹果丢了梨&#xff0c;一定要强迫自己抵制新鲜技术的诱惑。 网络安全其实是个广而深的领域…...

WEB:php_rce

背景知识 Linux命令 thinkPHPv5漏洞 题目 打开页面&#xff0c;页面显示为thinkphp v5的界面&#xff0c;可以判断框架为thinkPHP&#xff0c;可以去网上查找相关的漏洞 由题目可知&#xff0c;php rec是一个通过远程代码执行漏洞来攻击php程序的一种方式 因为不知道是php版…...

问题:idea启动项目错误提示【command line is too long. shorten command line】

问题&#xff1a;idea启动项目错误提示【command line is too long. shorten command line】 参考博客 问题描述 启动参数过长&#xff0c;启动项目&#xff0c;错误提示 原因分析 出现此问题的直接原因是&#xff1a;IDEA集成开发环境运行你的“源码”的时候&#xff08…...

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04 一、安装linux子系统 1.1、 启动或关闭Windows功能-适用于Linux的Windows子系统 1.2 WSL 官方文档 使用 WSL 在 Windows 上安装 Linux //1-安装 WSL 命令 wsl --install//2-检查正在运行的 WSL 版本&#xff1a;…...

子域名收集工具OneForAll的安装与使用-Win

子域名收集工具OneForAll的安装与使用-Win OneForAll是一款功能强大的子域名收集工具 GitHub地址&#xff1a;https://github.com/shmilylty/OneForAll Gitee地址&#xff1a;https://gitee.com/shmilylty/OneForAll 安装 1、python环境准备 OneForAll基于Python 3.6.0开发和…...

报数游戏、

描述 有n人围成一圈&#xff0c;顺序排号。从第1个人开始报数&#xff08;从1到3报数&#xff09;&#xff0c;凡报到3的人退出圈子&#xff0c;问最后留下的是原来的第几号的那位。。 输入 初始人数n 输出 最后一人的初始编号 输入样例 1 3 输出样例 1 2 输入样例 …...

规约模式:优雅设计与灵活应用

引言&#xff1a; 规约模式是软件开发中的重要设计原则&#xff0c;它们提供了一种优雅的、灵活的方式来构建高质量的系统。本文将通过实例演示规约模式的具体应用&#xff0c;带你了解这些原则的实战价值。 一、开放封闭原则 // 图形接口 public interface Shape {void dra…...

Ubuntu Server版 之 apache系列 安装、重启、开启,版本查看

安装之前首先要检测是否安装过 apt list --installed | grep tool tool&#xff1a;要检测的名称&#xff0c;如mysql、apache 、ngnix 等 安装 apache sudo apt install apache2 安装apache 默认是开启的 可以通过浏览器 检测一下 service apache stop # apache 停止服务…...

Redis学习路线(4)—— Redis实现项目缓存

一、什么是缓存 &#xff08;一&#xff09;概念&#xff1a;缓存就是数据交换的缓冲区&#xff08;称为Cache&#xff09;&#xff0c;是存储数据的临时区域&#xff0c;一般读写性能较高。 &#xff08;二&#xff09;常见缓存&#xff1a; 浏览器缓存&#xff0c;服务器缓…...

【Unity造轮子】实现一个类csgo的武器轮盘功能

文章目录 前言素材导入开始1.放背景和中间的圆圈&#xff0c;调整合适的宽高和位置2.添加选择图像框3.添加一些武器道具选择4.书写脚本RadialMenuManager5.绑定脚本和对象6.运行效果&#xff0c;按tab键开启关闭轮盘7.优化添加显示选中的武器文本8.添加鼠标选中放大的效果9.添加…...

代码随想录算法训练营第三十天 | 单调栈系列复习

单调栈系列复习 每日温度未看解答自己编写的青春版重点题解的代码日后再次复习重新写 下一个更大元素 I未看解答自己编写的青春版重点题解的代码日后再次复习重新写 下一个更大元素II未看解答自己编写的青春版重点题解的代码日后再次复习重新写 接雨水未看解答自己编写的青春版…...

redis数据未到过期时间被删除

1. 问题描述 使用了jeecgboot开发后端代码&#xff0c;代码设置的redis过期时间为24小时&#xff0c;部署使用的宝塔面板&#xff0c;在redis中看到的过期时间也是为24小时&#xff0c;但是并未到过期时间&#xff0c;数据就被删除。 2. 解决办法 观察了一下redis中的数据&a…...

32.选择器

选择器 html部分 <div class"toggle-container"><input type"checkbox" id"good" class"toggle"><label for"good" class"label"><div class"ball"></div></label&…...

Linux--验证命令行上运行的程序的父进程是bash

1.输入以下代码&#xff1a; #include <stdio.h> #include <unistd.h> int main() {printf("hello world: pid: %d, ppid: %d\n",getpid(),getppid());return 0; }2.编译得到可执行程序​​​ 3.运行得到ppid 4.输入指令 ps axj | head -1 &&am…...

MySQL数据库关于表的一系列操作

MySQL中的数据类型 varchar 动态字符串类型&#xff08;最长255位&#xff09;&#xff0c;可以根据实际长度来动态分配空间&#xff0c;例如&#xff1a;varchar(100) char 定长字符串&#xff08;最长255位&#xff09;&#xff0c;存储空间是固定的&#xff0c;例如&#…...

Spring基于注解管理bean及全注解开发

文章目录 spring概述Spring定义Spring核心Spring Framework的特点 基于注解管理bean依赖开启组件扫描使用注解定义Bean案例:Autowired注入属性注入set注入形参上注入只有一个构造函数&#xff0c;无注解Autowire注解和Qualifier注解联合 Resource注入Spring全注解开发 spring概…...

QtC++ 技术分析3 - IOStream

目录 iostreamscanf/printfiostream 整体架构流相关类流缓冲区 模板特化后整体结构文件流文件流对象创建常见文件流操作输出格式设定文件流状态 字符串流字符串流内部缓冲区字符串流使用 流缓冲区用户自定义 IO iostream scanf/printf 几种常见的输入输出流函数 scanf 从键盘…...

2023年Q2京东环境电器市场数据分析(京东数据产品)

今年Q2&#xff0c;环境电器市场中不少类目表现亮眼&#xff0c;尤其是以净水器、空气净化器、除湿机等为代表的环境健康电器。此外&#xff0c;像冷风扇这类具有强季节性特征的电器也呈现出比较好的增长态势。 接下来&#xff0c;结合具体数据我们一起来分析Q2环境电器市场中…...

TCP/UDP的首部

TCP/UDP首部信息 TCP首部第一个4字节第二个4字节与第三个4字节第四个4字节第五个4字节选项最大报文段长度&#xff08;MSS&#xff09;选项窗口扩大选项时间戳选项 什么时候发送RST包UDP首部 TCP首部 TCP 首部长度为20字节&#xff0c;加上选项部分最大可达60字节。 第一个4…...

Kubernetes(K8s)从入门到精通系列之四:K8s的基本概念和术语之集群类

Kubernetes K8s从入门到精通系列之四:K8s的基本概念和术语之集群类 一、Master二、Node三、命名空间集群表示一个由Master和Node组成的K8s集群。 一、Master Master指的是集群的控制节点。在每个K8s集群都需要有一个或一组被称为Master的节点,来负责整个集群的管理和控制。M…...

黑马头条---day1

手机端查看 docker 容器&#xff0c;镜像操作命令 1、docker删除所有镜像命令 删除所有镜像的命令是Docker中一个非常常见的操作。下面是具体的实现步骤和命令示例&#xff1a; $ docker stop $(docker ps -aq) 停止所有正在运行的容器。 $ docker rm $(docker ps -aq) 删…...

【序列化工具JdkSerialize和Protostuff】

序列化工具对比 JdkSerialize&#xff1a;java内置的序列化能将实现了Serilazable接口的对象进行序列化和反序列化&#xff0c; ObjectOutputStream的writeObject()方法可序列化对象生成字节数组 Protostuff&#xff1a;google开源的protostuff采用更为紧凑的二进制数组&#…...

C++ 多线程编程导论(下)

文章目录 参考资料线程安全&#xff08;续&#xff09;门闩与屏障——latch 对象与 barrier 对象门闩&#xff08;latch&#xff09;屏障&#xff08;barrier&#xff09; 一次性调用——once_flag 对象与 call_once 函数 异步任务未来与承诺——future 对象与 promise 对象fut…...

Java并发系列之一:JVM线程模型

什么是线程模型&#xff1a; Java字节码运行在JVM中&#xff0c;JVM运行在各个操作系统上。所以当JVM想要进行线程创建回收这种操作时&#xff0c;势必需要调用操作系统的相关接口。也就是说&#xff0c;JVM线程与操作系统线程之间存在着某种映射关系&#xff0c;这两种不同维…...

容灾独家技术揭秘:HyperBDR无主机数据同步技术

01、一对一单机热备-传统灾备方式 单机热备是一种备份解决方案&#xff0c;它使用两台服务器来确保高可用性&#xff0c;是市场上最为常见的灾备模式。 在单机热备中&#xff0c;一台主服务器和一台备用服务器保持同步&#xff0c;以确保在主服务器出现故障或宕机时可以立即切换…...

FANUC机器人SRVO-050碰撞检测报警和SRVO-053干扰值过大故障报警总结

FANUC机器人SRVO-050碰撞检测报警和SRVO-053干扰值过大故障报警总结 前面和大家分享了关于SRVO-050碰撞检测报警和SRVO-053干扰值过大的原因分析以及处理方法,感兴趣的朋友可以参考以下链接中的内容: FANUC机器人SRVO-050碰撞检测报警原因分析及处理对策...

微信如何提高回复信息速度?

规范流程话术有什么用&#xff1f;为了提高回复客户的效率和质量&#xff0c;可以事先设计好的一套标准化的对话模板。它通常包括多个环节和问题&#xff0c;帮助客服人员或销售人员在与客户沟通时&#xff0c;按照标准化的流程进行&#xff0c;以提高工作效率和客户满意度。 如…...

模拟Stevens Lewis描述的小型飞机纵向动力学的非线性动态反演控制器研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码实现 &#x1f4a5;1 概述 针对Stevens和Lewis描述的小型飞机纵向动力学的非线性动态&#xff0c;研究非线性动态反演控制器可以是一个有趣的课题。动态反演控制器的目标…...

【C++从0到王者】第十二站:vector基本使用

文章目录 一、vector基本介绍二、vector的基本使用三、vector\<char> 和string的区别四、vector接口介绍1.vector的模板参数2.构造函数3.迭代器4.size和max_size5.resize和reserve6.operator[]和at7.front和back8.data9.push_back和pop_back10.insert和erase11.assign12.…...