背景
使用co.elastic.clients基于Elasticsearch API 正式文档,不会因版本不一致出现诸多问题,如jar报冲突等,可兼容SpringBoot1.X、2.x。
Maven依赖
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.0</version></dependency><!-- ES 核心包 --><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.1.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>1.5.4.RELEASE</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency><dependency><groupId>org.glassfish</groupId><artifactId>jakarta.json</artifactId><version>2.0.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.7</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.6</version></dependency><dependency><groupId>com.github.yangtu222</groupId><artifactId>BeanUtils</artifactId><version>1.0.9</version></dependency>
客户端配置
非加密模式
@Data@Configuration@ConfigurationProperties(prefix ="elasticsearch")publicclassElasticSearchConfig{privateString host;privateInteger port;@BeanpublicElasticsearchClientelasticsearchClient(){RestClient client =RestClient.builder(newHttpHost(host, port,"http")).build();ElasticsearchTransport transport =newRestClientTransport(client,newJacksonJsonpMapper());returnnewElasticsearchClient(transport);}
加密模式
@BeanpublicElasticsearchClientelasticsearchClient(){ElasticsearchTransport transport =getElasticsearchTransport();returnnewElasticsearchClient(transport);}@BeanpublicElasticsearchAsyncClientelasticsearchAsyncClient(){ElasticsearchTransport transport =getElasticsearchTransport();returnnewElasticsearchAsyncClient(transport);}privateElasticsearchTransportgetElasticsearchTransport(){// Create the low-level clientfinalCredentialsProvider credentialsProvider =newBasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,newUsernamePasswordCredentials(username, password));Path caCertificatePath =Paths.get(path);SSLContext sslContext =null;try{CertificateFactory factory =CertificateFactory.getInstance("X.509");Certificate trustedCa;try(InputStream is =Files.newInputStream(caCertificatePath)){
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);}SSLContext finalSslContext = sslContext;RestClientBuilder builder =RestClient.builder(newHttpHost(host, port, scheme)).setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
.setSSLContext(finalSslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setDefaultCredentialsProvider(credentialsProvider));RestClient client = builder.build();returnnewRestClientTransport(client,newJacksonJsonpMapper());}
查询
完全匹配-TermQuery
terms和term的查询机制是一样的,都不会将指定的查询关键字进行分词,直接去分词库中匹配,找到相应文档内容。
Query q =TermQuery.of(t -> t.field("filed").value(value))._toQuery();
模糊匹配-FuzzyQuery
Query q=FuzzyQuery.of(t -> t.field("filed").value(value))._toQuery();
in查询-TermsQuery
主键id可通过IdsQuery
List<FieldValue> values =newArrayList<>();for(Long id : list){
values.add(FieldValue.of(id));}Query idsQuery =TermsQuery.of(t -> t.field("filed").terms(newTermsQueryField.Builder().value(values).build()))._toQuery();
时间范围查询-Range
将日期转为时间戳查询 精确到毫秒
Query byTime =RangeQuery.of(r -> r
.field("times").gte(JsonData.of(startTime.getTime())).lte(JsonData.of(endTime.getTime())))._toQuery();
排序-Sort
SortOptions.Builder sb =newSortOptions.Builder();
sb.field((f)->{
f.order(SortOrder.Desc);
f.field("times");return f;});SortOptions build = sb.build();List<SortOptions> builders =Arrays.asList(build);
组合分页查询-Bool
must: 所有的条件,用must组合在一起,表示And的意思
must_not:将must_not中的条件,全部都不能匹配,表示Not的意思
should:所有的条件,用should组合在一起,表示Or的意思
SearchRequest searchRequest =newSearchRequest.Builder().index("index").query(q -> q
.bool(
b ->{
b.must(q);
b.should(q1);return b;})).from(pageSize * pageNum).size(pageSize).sort(builders).build();SearchResponse<HashMap> search = client.search(searchRequest,HashMap.class);
扩展
文本匹配不到问题
因ES分词处理导致匹配不到
解决:
不需要做模糊查询的字段,使用keyword代替text,避免创建索引的时候对这些词进行分词。
我不知将去何方,但我已经在路上。——宫崎骏《千与千寻》
版权归原作者 三省同学 所有, 如有侵权,请联系我们删除。