目录
1. 初始化 RestHighLevelClient 客户端
- EsConfigModel.java 读取properties文件中es相关配置
# elastic
jdbc.es73.host=localhost
jdbc.es73.port=9200
jdbc.es73.queryType=http
jdbc.es73.username=elastic
jdbc.es73.password=elastic
package com.nuts.common.config;
import org.springframework.stereotype.Component;
import com.nuts.framework.PlatformAPI;
@Component
public class EsConfigModel {
private String esHost;
private Integer esPort;
private String queryType;
private String userName;
private String userPwd;
public EsConfigModel() {
esHost = PlatformAPI.getSysConfigValue("jdbc.es73.host");
esPort = Integer.parseInt(PlatformAPI.getSysConfigValue("jdbc.es73.port"));
queryType = PlatformAPI.getSysConfigValue("jdbc.es73.queryType");
userName = PlatformAPI.getSysConfigValue("jdbc.es73.username");
userPwd = PlatformAPI.getSysConfigValue("jdbc.es73.password");
}
public void setEsHost(String esHost) {
this.esHost = PlatformAPI.getSysConfigValue("jdbc.es73.host");
}
public void setEsPort(Integer esPort) {
this.esPort = Integer.parseInt(PlatformAPI.getSysConfigValue("jdbc.es73.port"));
}
public void setQueryType(String queryType) {
this.queryType = PlatformAPI.getSysConfigValue("jdbc.es73.queryType");
}
public void setUserName(String userName) {
this.userName = PlatformAPI.getSysConfigValue("jdbc.es73.username");
}
public void setUserPwd(String userPwd) {
this.userPwd = PlatformAPI.getSysConfigValue("jdbc.es73.password");
}
public String getEsHost() {
return esHost;
}
public Integer getEsPort() {
return esPort;
}
public String getQueryType() {
return queryType;
}
public String getUserName() {
return userName;
}
public String getUserPwd() {
return userPwd;
}
}
注:PlatformAPI.getSysConfigValue()各自需替换为读取配置文件属性方法即可。
- ElasticSearchConfig.java
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.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchConfig {
@Autowired
EsConfigModel esConfigModel;
/**
* 项目主要使用RestHighLevelClient,对于低级的客户端有些功能无法使用(需要用下面的client)
* @return
*/
@Bean
public RestHighLevelClient restHighLevelClient(){
//创建HttpHost数组,其中存放es主机和端口的配置信息
//初始化ES操作客户端
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(esConfigModel.getUserName(), esConfigModel.getUserPwd()));
HttpHost httpHost = new HttpHost(esConfigModel.getEsHost(), esConfigModel.getEsPort(), esConfigModel.getQueryType());
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(httpHost)
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
);
return restHighLevelClient;
}
@Bean
public RestClient restClient(){
//创建HttpHost数组,其中存放es主机和端口的配置信息
HttpHost httpHost = new HttpHost(esConfigModel.getEsHost(), esConfigModel.getEsPort(), esConfigModel.getQueryType());
RestClient restClient = RestClient.builder(httpHost).build();
return restClient;
}
}
2. 常用的几种查询类型
2.1 MultiMatchQuery 多字段分词查询
/******************************** MultiMatchQuery 多字段查询 **********************************/
public void testMultiMatchQuery() throws IOException, ParseException {
// 搜索请求对象 .SearchRequest(String... indices)
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// multiMatchQuery(Object text, String... fieldNames)
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("spring css", "name", "description")
.minimumShouldMatch("50%");
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
Long total = totalHits.value;
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
/********************** 解析数据 ***********************/
// 日期格式化对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (SearchHit hit : searchHits) {
// 文档的主键
String id = hit.getId();
// 源文档内容(key:字段名 value:对应值)
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
// 由于前边设置了源文档字段过虑,这时description是取不到的
String description = (String) sourceAsMap.get("description");
// 学习模式
String studymodel = (String) sourceAsMap.get("studymodel");
// 价格
Double price = (Double) sourceAsMap.get("price");
// 日期
Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp"));
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
2.2 MatchQuery 字段查询
/******************************** MatchQuery 字段查询 **********************************/
public void testMatchQuery() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// MatchQuery 查询description字段 matchQuery(String name, Object text)
searchSourceBuilder.query(QueryBuilders.matchQuery("description", "spring开发框架"));
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
}
2.3 termQuery term查询(精准、不分词查询)
/**************************** termQuery term查询 **********************/
public void testTermQuery() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// termQuery(String name, String value)
searchSourceBuilder.query(QueryBuilders.termQuery("name.keyword", "spring boot"));
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
}
注意:term查询对于搜索的关键字不会分词,所以搜索的字段也不应该是分词字段。如果字段是分词字段,考虑使用其子字段类型 .keyword。
具体可看这篇文章: https://blog.csdn.net/u011821334/article/details/100979286?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
2.4 termsQuery(String name, String… values)
/******************************** termsQuery(String name, String... values) 字段多值查询 **********************************/
public void testTermsQuery() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// 根据id查询
// 定义id
String[] ids = new String[] { "1", "2" };
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
}
2.5 BoolQuery
/******************************** BoolQuery **********************************/
public void testBoolQuery() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// boolQuery搜索方式
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(90).lte(100));
boolQueryBuilder.must(QueryBuilders.termQuery("studymodel", "201001"));
// boolQueryBuilder.should();
searchSourceBuilder.query(boolQueryBuilder);
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
}
2.6 分页和排序
/******************************** 分页和排序 **********************************/
public void testSearchPage() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 设置分页参数
// 页码
int page = 1;
// 每页记录数
int size = 1;
// 计算出记录起始下标
int from = (page - 1) * size;
searchSourceBuilder.from(from);// 起始记录下标,从0开始
searchSourceBuilder.size(size);// 每页显示的记录数
// 添加排序
searchSourceBuilder.sort("studymodel", SortOrder.DESC);
searchSourceBuilder.sort("price", SortOrder.ASC);
// 搜索方式
// termQuery(String name, String value)
searchSourceBuilder.query(QueryBuilders.termQuery("name", "spring boot"));
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name.keyword", "studymodel", "price", "timestamp" }, new String[] {});
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
}
注:排序的字段,不能是分词字段。否则查询异常。
2.7 关键字高亮
/******************************** Highlight 高亮 **********************************/
public void testHighlight() throws IOException, ParseException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("elasticsearch_test");
// 指定类型
searchRequest.types("doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// termQuery(String name, String value)
searchSourceBuilder.query(QueryBuilders.termQuery("name", "spring"));
// 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[] { "name", "studymodel", "price", "timestamp" }, new String[] {});
// 设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<tag>");
highlightBuilder.postTags("</tag>");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
searchSourceBuilder.highlighter(highlightBuilder);
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
TotalHits totalHits = hits.getTotalHits();
// 得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
// 日期格式化对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (SearchHit hit : searchHits) {
// 文档的主键
String id = hit.getId();
// 源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 源文档的name字段内容
String name = (String) sourceAsMap.get("name");
// 取出高亮字段
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields != null) {
// 取出name高亮字段
HighlightField nameHighlightField = highlightFields.get("name");
if (nameHighlightField != null) {
Text[] fragments = nameHighlightField.getFragments();
StringBuffer stringBuffer = new StringBuffer();
for (Text text : fragments) {
stringBuffer.append(text);
}
name = stringBuffer.toString();
}
}
// 由于前边设置了源文档字段过虑,这时description是取不到的
String description = (String) sourceAsMap.get("description");
// 学习模式
String studymodel = (String) sourceAsMap.get("studymodel");
// 价格
Double price = (Double) sourceAsMap.get("price");
// 日期
Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp"));
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}