ES集成SpringBoot
1、原生的mave
2、找对象
3、分析这个类中的方法
配置基本项目
发现默认的版本是6.8.6,版本不符,所以要自定义es版本
写一个config将对象注入进来
分析springboot源码
es的默认配置
虽然导入了三个类,但都是静态内部类,核心类就一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | /* * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.autoconfigure.elasticsearch.rest; import java.time.Duration; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Elasticsearch rest client infrastructure configurations. * * @author Brian Clozel * @author Stephane Nicoll */ class RestClientConfigurations { @Configuration (proxyBeanMethods = false ) static class RestClientBuilderConfiguration { // RestClientBuilder @Bean @ConditionalOnMissingBean RestClientBuilder elasticsearchRestClientBuilder(RestClientProperties properties, ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) { HttpHost[] hosts = properties.getUris().stream().map(HttpHost::create).toArray(HttpHost[]:: new ); RestClientBuilder builder = RestClient.builder(hosts); PropertyMapper map = PropertyMapper.get(); map.from(properties::getUsername).whenHasText().to((username) -> { CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(), properties.getPassword()); credentialsProvider.setCredentials(AuthScope.ANY, credentials); builder.setHttpClientConfigCallback( (httpClientBuilder) -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); }); builder.setRequestConfigCallback((requestConfigBuilder) -> { map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis) .to(requestConfigBuilder::setConnectTimeout); map.from(properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis) .to(requestConfigBuilder::setSocketTimeout); return requestConfigBuilder; }); builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); return builder; } } @Configuration (proxyBeanMethods = false ) @ConditionalOnClass (RestHighLevelClient. class ) static class RestHighLevelClientConfiguration { //RestHighLevelClient 高级客户端 @Bean @ConditionalOnMissingBean RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) { return new RestHighLevelClient(restClientBuilder); } @Bean @ConditionalOnMissingBean RestClient elasticsearchRestClient(RestClientBuilder builder, ObjectProvider<RestHighLevelClient> restHighLevelClient) { RestHighLevelClient client = restHighLevelClient.getIfUnique(); if (client != null ) { return client.getLowLevelClient(); } return builder.build(); } } @Configuration (proxyBeanMethods = false ) static class RestClientFallbackConfiguration { //RestClient普通客户端 @Bean @ConditionalOnMissingBean RestClient elasticsearchRestClient(RestClientBuilder builder) { return builder.build(); } } } |
测试高级客户端的api
索引和文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | package com.renzhe; import com.alibaba.fastjson.JSON; import com.renzhe.pojo.User; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; 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.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.IndicesClient; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.CreateIndexResponse; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.TimeUnit; /** * es 7.6.x 高级客户端测试 Api * */ @SpringBootTest class RenzheEsApiApplicationTests { //面向对象来操作 @Autowired @Qualifier ( "restHighLevelClient" ) //注入的时候变量名会去匹配自己定义的方法名,如果变量名与方法名不一样那么就会报红 //如果想使用自定义的变量名 就加上@Qualifier注解去匹配自己的定义的方法名 private RestHighLevelClient client; //测试索引的创建 Request @Test void testCreateIndex() throws IOException { //1、创建索引请求 CreateIndexRequest request = new CreateIndexRequest( "renzhe_index" ); //2、客户端执行请求 IndicesClient,请求后获得响应 会抛出IO异常 CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT); System.out.println(createIndexResponse); } //测试获取索引 @Test void testExistIndex() throws IOException{ GetIndexRequest request = new GetIndexRequest( "renzhe_index" ); boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); System.out.println(exists); } // 测试删除索引 删除请求后获取响应 @Test void testDeleteIndex() throws IOException { DeleteIndexRequest request = new DeleteIndexRequest( "renzhe_index" ); AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT); System.out.println(delete); } //测试添加文档 @Test void testAddDocument() throws IOException { //创建对象 User user = new User( "renzhe" , 3 ); //创建请求 (连接renzhe_index的索引库) IndexRequest request = new IndexRequest( "renzhe_index" ); // 规则 put /renzhe_index/_doc/1 request.id( "1" ); request.timeout(TimeValue.timeValueSeconds( 1 )); request.timeout( "1s" ); //将数据放入请求 所有的数据都是json数据 所以要引入alibaba的fastjson request.source(JSON.toJSONString(user), XContentType.JSON); //客户端发送请求 获取响应的结果 IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT); System.out.println(indexResponse.toString()); System.out.println(indexResponse.status()); //对应命令中返回的状态 } //获取文档,判断是否存在 get /index/_doc/1 @Test void testIsExists() throws IOException{ GetRequest getRequest = new GetRequest( "renzhe_index" , "1" ); //不获取返回的_source的上下文了 getRequest.fetchSourceContext( new FetchSourceContext( false )); getRequest.storedFields( "_none_" ); boolean exists = client.exists(getRequest, RequestOptions.DEFAULT); System.out.println(exists); } //获取文档的信息 @Test void testGetDocument() throws IOException{ GetRequest getRequest = new GetRequest( "renzhe_index" , "1" ); GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); System.out.println(getResponse.getSourceAsString()); //打印文档内容 System.out.println(getResponse); //这里返回的全部内容和命令是一样的 } //更新文档内容 @Test void testUpdateDocument() throws IOException{ UpdateRequest updateRequest = new UpdateRequest( "renzhe_index" , "1" ); updateRequest.timeout( "1s" ); User user = new User( "hello world" , 9 ); updateRequest.doc(JSON.toJSONString(user),XContentType.JSON); UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT); System.out.println(updateResponse); } //删除文档记录 @Test void testDeleteDocument() throws IOException{ DeleteRequest deleteRequest = new DeleteRequest( "renzhe_index" , "1" ); deleteRequest.timeout( "1s" ); DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT); System.out.println(delete); } //特殊的 真实项目 都是需要大批量数据的导入 @Test void testBulkRequest() throws IOException{ BulkRequest bulkRequest = new BulkRequest(); bulkRequest.timeout( "1s" ); ArrayList<User> userList = new ArrayList(); userList.add( new User( "renzhe1" , 1 )); userList.add( new User( "renzhe2" , 1 )); userList.add( new User( "renzhe3" , 1 )); userList.add( new User( "renzhe4" , 1 )); userList.add( new User( "renzhe5" , 1 )); userList.add( new User( "renzhe6" , 1 )); userList.add( new User( "renzhe7" , 1 )); userList.add( new User( "renzhe8" , 1 )); userList.add( new User( "renzhe9" , 1 )); //批处理请求 for ( int i = 0 ; i < userList.size(); i++) { //批量更新和批量删除在这里修改对应的请求即可 bulkRequest.add( new IndexRequest( "renzhe_index" ) .id( "" +(i+ 1 )) .source(JSON.toJSONString(userList.get(i)),XContentType.JSON)); } BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT); System.out.println(bulkResponse.hasFailures()); } //查询 @Test void testSearch() throws IOException{ SearchRequest searchRequest = new SearchRequest( "renzhe_index" ); //构建搜索的条件 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //QueryBuilders.termQuery() 精确匹配 TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery( "name" , "renzhe1" ); //QueryBuilders.matchAllQuery(); sourceBuilder.query(termQueryBuilder); //分页 默认有 可以不写 /*sourceBuilder.from(); sourceBuilder.size();*/ sourceBuilder.timeout( new TimeValue( 60 , TimeUnit.SECONDS)); //构建搜索 searchRequest.source(sourceBuilder); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); System.out.println(JSON.toJSONString(searchHits)); System.out.println( "===============================" ); for (SearchHit documentFields : searchResponse.getHits().getHits()) { System.out.println(documentFields.getSourceAsMap()); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义