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> 3.1 .1 < /version> < relativePath/> < ! -- lookup parent from repository --> < /parent> < groupId> com.xxx< /groupId> < artifactId> elastic< /artifactId> < version> 0.0 .1-SNAPSHOT< /version> < name> elastic< /name> < description> Demo project for Spring Boot< /description> < properties> < java.version> 1 7 < /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.plugin< /groupId> < artifactId> x-pack-sql-jdbc< /artifactId> < version> 8.7 .1 < /version> < /dependency> < dependency> < groupId> co.elastic.clients< /groupId> < artifactId> elasticsearch-java< /artifactId> < version> 8.7 .1 < /version> < /dependency> < dependency> < groupId> com.fasterxml.jackson.core< /groupId> < artifactId> jackson-databind< /artifactId> < version> 2.12 .3 < /version> < /dependency> < dependency> < groupId> jakarta.json< /groupId> < artifactId> jakarta.json-api< /artifactId> < version> 2.0 .1 < /version> < /dependency> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-web< /artifactId> < version> 3.1 .1 < /version> < /dependency> < dependency> < groupId> org.apache.logging.log4j< /groupId> < artifactId> log4j-api< /artifactId> < version> 2.17 .2 < /version> < /dependency> < dependency> < groupId> org.apache.logging.log4j< /groupId> < artifactId> log4j-core< /artifactId> < version> 2.17 .2 < /version> < /dependency> < dependency> < groupId> org.projectlombok< /groupId> < artifactId> lombok< /artifactId> < version> 1.18 .28 < /version> < /dependency> < /dependencies> < build> < plugins> < plugin> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-maven-plugin< /artifactId> < /plugin> < /plugins> < /build> < /project>
spring:elasticsearch:rest:enable: true host: 9b4xxxxxxb829199076e3602b516.us-central1.gcp.cloud.es.ioport: 443 username: elasticpassword: 密码index: indexName
配置ElasticSearchConfig
package com.xxx.elastic.config; import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; //import javax.annotation.PostConstruct;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; /*** es8的Java客户端配置*/
@Configuration
//@Slf4j
public class ElasticSearchConfig { @Value( "${spring.elasticsearch.rest.host} " ) private String host ; @Value( "${spring.elasticsearch.rest.enable} " ) private boolean enable ; @Value( "${spring.elasticsearch.rest.port} " ) private int port; @Value( "${spring.elasticsearch.rest.username} " ) private String userName; @Value( "${spring.elasticsearch.rest.password} " ) private String passWord;
// @Value( "${spring.elasticsearch.rest.crtName} " )
// private String tempCrtName; private static String crtName; // @PostConstruct
// private void init ( ) {
// crtName = tempCrtName;
// } /*** 解析配置的字符串,转为HttpHost对象数组** @return*/private HttpHost toHttpHost ( ) { HttpHost httpHost = new HttpHost( host, port, "https" ) ; return httpHost; } /*** 同步客户端* @return* @throws Exception*/@Beanpublic ElasticsearchClient clientBySync( ) throws Exception { ElasticsearchTransport transport = getElasticsearchTransport( userName, passWord, toHttpHost( )) ; return new ElasticsearchClient( transport) ; } /*** 异步客户端* @return* @throws Exception*/@Beanpublic ElasticsearchAsyncClient clientByAsync( ) throws Exception { ElasticsearchTransport transport = getElasticsearchTransport( userName, passWord, toHttpHost( )) ; return new ElasticsearchAsyncClient( transport) ; } /*** 传输对象* @return* @throws Exception*/@Beanpublic ElasticsearchTransport getTransport( ) throws Exception { return getElasticsearchTransport( userName, passWord, toHttpHost( )) ; } private static SSLContext buildSSLContext ( ) { ClassPathResource resource = new ClassPathResource( crtName) ; SSLContext sslContext = null; try { CertificateFactory factory = CertificateFactory.getInstance( "X.509" ) ; Certificate trustedCa; try ( InputStream is = resource.getInputStream( )) { trustedCa = factory.generateCertificate( is) ; } KeyStore trustStore = KeyStore.getInstance( "pkcs12" ) ; trustStore.load( null, null) ; trustStore.setCertificateEntry( "ca" , trustedCa) ; SSLContextBuilder sslContextBuilder = SSLContexts.custom( ) .loadTrustMaterial( trustStore, null) ; sslContext = sslContextBuilder.build( ) ; } catch ( CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {
// log.error( "ES连接认证失败" , e) ; } return sslContext; } private static ElasticsearchTransport getElasticsearchTransport( String username, String passwd, HttpHost.. . hosts) { // 账号密码的配置final CredentialsProvider credentialsProvider = new BasicCredentialsProvider( ) ; credentialsProvider.setCredentials( AuthScope.ANY, new UsernamePasswordCredentials( username, passwd )) ; // 自签证书的设置,并且还包含了账号密码RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
// .setSSLContext( buildSSLContext( )) .setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE ) .setDefaultCredentialsProvider( credentialsProvider) ; // 用builder创建RestClient对象RestClient client = RestClient.builder( hosts) .setHttpClientConfigCallback( callback) .build( ) ; return new RestClientTransport( client, new JacksonJsonpMapper( )) ; } }
import lombok.Data; /*** @Date 2023 /7/15 12 :24*/
@Data
public class User { private Integer Id; private String Username; private String Sex; private Integer Age;
}
package com.xxx.elastic.config; import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.transport.ElasticsearchTransport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; @RestController
public class ESController { @Autowiredprivate ElasticsearchClient syncClient; @Autowiredprivate ElasticsearchAsyncClient asyncClient; @Autowiredprivate ElasticsearchTransport transport; @GetMapping( "/init" ) public void initElastic( ) throws Exception{ //获取索引客户端对象ElasticsearchIndicesClient indices = syncClient.indices( ) ; //创建索引 采用构建器的方式构建( 在创建之前需要先判断该索引是否存在) boolean exists = indices.exists( u -> u.index( "userhahah" )) .value( ) ; if ( exists) { System.out.println( "该索引已存在!!" ) ; } else { CreateIndexResponse createIndexResponse = indices.create( c -> c.index( "userhahah" )) ; boolean acknowledged = createIndexResponse.acknowledged( ) ; System.out.println( acknowledged) ; } //查询索引GetIndexResponse getResponse = indices.get( g -> g.index( "userhahah" )) ; System.out.println( "查询索引:" +getResponse) ; //删除索引DeleteIndexResponse deleteResponse = indices.delete( d -> d.index( "userhahah" )) ; System.out.println( "删除索引:" +deleteResponse.acknowledged( )) ; } // 创建文档@GetMapping( "/initwd" ) public void initElasticwd( ) throws Exception{ //获取索引客户端对象ElasticsearchIndicesClient indices = syncClient.indices( ) ; //创建文档User user = new User( ) ; user.setId( 1001 ) ; user.setUsername( "阿桃" ) ; user.setSex( "男" ) ; user.setAge( 26 ) ; Result result = syncClient.create( c -> c.index( "userhahah" ) .id( "1001" ) .document( user)) .result( ) ; System.out.println( "创建文档:" +result) ; //批量创建文档List< User> users = new ArrayList<> ( ) ; //假设有数据syncClient.bulk( b -> { //批量创建操作users.forEach( u -> { //遍历需要创建的数据b.operations( o -> o.create( c -> c.index( "userhahah" ) .id( u.getId( ) .toString( )) .document( u)) ) ; } ) ; return b; } ) ; //删除文档syncClient.delete( d -> d.index( "userhahah" ) .id( "1001" )) ; //查询文档HitsMetadata< Object> hits = syncClient.search( s -> { s.query( q -> q.match( m -> m.field( "username" ) .query( "阿桃" ) )) ; return s; } , Object.class) .hits( ) ; transport.close( ) ; //同步操作时需要关闭,异步时不需要关闭} @GetMapping( "/initAsync" ) public void initAsyncElastic( ) throws Exception{ //获取索引异步客户端对象ElasticsearchIndicesAsyncClient indices = asyncClient.indices( ) ; //异步调用无法直接获取操作反馈,只能通过回调进行判断//情况一indices.create( c -> c.index( "newUser" )) .whenComplete( ( response,error) -> { if( null != response) { System.out.println( response.acknowledged( )) ; } else { System.out.println( error) ; } } ) ; //情况二 thenApply中获取过acknowledged以后后续不用再获取了//thenApply是在创建完成后执行的,在whenComplete之前indices.create( c -> c.index( "newUser" )) .thenApply( response -> response.acknowledged( )) .whenComplete( ( response,error) -> { if( response.equals( true)) { System.out.println( response) ; } else { System.out.println( error) ; } } ) ; } }
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.HighlightField;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient;
import com.xxx.elastic.config.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; @SpringBootTest
class ElasticApplicationTests { @Autowiredprivate ElasticsearchClient esClient; @Testvoid contextLoads( ) throws IOException { //获取索引客户端对象
// esClient.indices( ) .create( c -> c
// .index( "products" )
// ) ; Product product = new Product( "bk-1" , "City-bike" , 123 ) ; IndexResponse response = esClient.index( i -> i.index( "products" ) .id( product.getSku( )) .document( product) ) ; System.out.println( "Indexed with version " + response.version( )) ; GetResponse< Product> getresponse = esClient.get( g -> g.index( "products" ) .id( product.getSku( )) ,Product.class) ; if ( getresponse.found( )) { Product getproduct = getresponse.source( ) ; System.out.println( "Product name " + getproduct.getName( )) ; } else { System.out.println( "Product not found" ) ; } } @Testvoid contextLoa( ) throws IOException { String searchText = "Updated" ; SearchResponse< Product> response = esClient.search( s -> s.index( "products" ) .query( q -> q.match( t -> t.field( "name" ) .query( searchText) ) ) ,Product.class) ;
// HitsMetadata< Product> hits = response.hits( ) ; System.out.println( "111" ) ; } @Testvoid contextLo( ) throws IOException { esClient.delete( d -> d.index( "products" ) .id( "bk-1" )) ; } @Testvoid context( ) throws IOException { Product product = new Product( "bk-1" , "Updated name" , 12356 ) ; esClient.update( u -> u.index( "products" ) .id( product.getSku( )) .doc( product) , Product.class) ; }
}