Java查询Elasticsearch(RestHighLevelClient)

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);
		}

	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值