文章目录
一、Java Client 集成
介绍如何使用Java REST High-Level Client对Elasticsearch进行多种高级查询操作,包括全文检索、精确查询、布尔查询、过滤查询及高亮显示等,通过具体代码示例展示查询效果。(以7.10版本为例)
1、创建Maven项目添加坐标
<dependencies>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.10.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
2、编写测试类
public class ClientTest {
private static final RequestOptions COMMON_OPTIONS;
private static final String USERNAME = "****";
private static final String PASSWORD = "****";
private static final String HTTP_HOST = "*************";
private static final Integer PORT = 9200;
private static final String INDEX_NAME = "******";
private static final String TYPE_NAME = "********";
private static final String DOC_ID = "";//根据需要更改
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 默认缓存限制为100MB,此处修改为30MB。
builder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory
.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
//抽取共用代码(认证,创建客户端对象)
private RestHighLevelClient getHighClient() {
// 阿里云ES集群需要basic auth验证。
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
//访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(USERNAME, PASSWORD));
// 通过builder创建rest client,配置http client的HttpClientConfigCallback。
// 单击所创建的Elasticsearch实例ID,在基本信息页面获取公网地址,即为ES集群地址。
RestClientBuilder builder = RestClient.builder(new HttpHost(HTTP_HOST, PORT))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
// RestHighLevelClient实例通过REST low-level client builder进行构造。
return new RestHighLevelClient(builder);
}
/**
* 查询全部
**/
@Test
public void testMatchAllQuery() {
RestHighLevelClient highClient = getHighClient();
try {
//创建搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定搜索类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜索方式
//matchAllQuery搜索全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age","description"}, new String[]{});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果命中的记录
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
System.out.println("匹配总记录数:" + totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String age = (String) sourceAsMap.get("age");
System.out.println("name:" + name + ",age:" + age);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
3、查询全部并排序
@Test
public void testMatchAllQueryAndSort() {
RestHighLevelClient highClient = getHighClient();
try {
//创建搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定搜索类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜索方式
//matchAllQuery搜索全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age"}, new String[]{});
//添加排序
searchSourceBuilder.sort("age", SortOrder.DESC);
//searchSourceBuilder.sort("age", SortOrder.ASC);
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果命中的记录
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
System.out.println("匹配总记录数:" + totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String age = (String) sourceAsMap.get("age");
System.out.println("name:" + name + ",age:" + age);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
4、分页查询
@Test
public void testPagingQuery() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置分页参数
//页码
int page = 1;
//每页记录数
int size = 1;
//计算出记录起始下标
int from = (page - 1) * size;
searchSourceBuilder.from(from);//起始记录下标,从0开始
searchSourceBuilder.size(size);//每页显示的记录数
//搜索方式
//matchAllQuery搜索全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name"}, new String[]{"age"});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
System.out.println("总记录数:" + totalHits);
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String age = (String) sourceAsMap.get("age");
//由于前边设置了源文档字段过虑,这时age是取不到的
System.out.println("name:" + name + ",age:" + age);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
5、TermQuery查询
@Test
public void testTermQuery() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜索方式
searchSourceBuilder.query(QueryBuilders.termQuery("name", "李四"));
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age"}, new String[]{"description"});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
System.out.println("总记录数:" + totalHits);
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
//由于前边设置了源文档字段过虑,这时description是取不到的
String description = (String) sourceAsMap.get("description");
String age = (String) sourceAsMap.get("age");
System.out.println("name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
6、根据ids精确查询
@Test
public void testTermQueryByIds() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//定义id
String[] ids = new String[]{"1", "2"};
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String age = (String) sourceAsMap.get("age");
String description = (String) sourceAsMap.get("description");
System.out.println("name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
7、MatchQuery
@Test
public void testMatchQuery() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜索方式1:MatchQuery
// searchSourceBuilder.query(QueryBuilders.matchQuery("description", "样样精通")
// .minimumShouldMatch("80%"));
//搜索方式2:MultiMatchQuery
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("李四是一个工程师", "name", "description")
.minimumShouldMatch("50%")
.field("name", 10));//权重提升10倍
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
String age = (String) sourceAsMap.get("age");
System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
8、BoolQuery搜索方式
@Test
public void testBoolQuery() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//boolQuery搜索方式
//先定义一个MultiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四", "name", "description")
.minimumShouldMatch("50%")
.field("name", 10);
//再定义一个termQuery
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("age", "22");
//定义一个boolQuery,必须满足两个条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.must(termQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
System.out.println("总记录数:"+totalHits);
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
String age = (String) sourceAsMap.get("age");
System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
9、Filter搜索方式/sort搜索方式
@Test
public void testFilter() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//boolQuery搜索方式
//先定义一个MultiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四是一个伟大的工程师", "name", "description")
.minimumShouldMatch("50%")
.field("name", 10);
//定义一个boolQuery
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
//定义过虑器
boolQueryBuilder.filter(QueryBuilders.termQuery("name", "李四"));//不再分次,精确匹配查询
boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(21).lte(30));//范围查询
searchSourceBuilder.query(boolQueryBuilder);
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age", "description"}, new String[]{});
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
String age = (String) sourceAsMap.get("age");
System.out.println("ID:" + id + "name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
10、Highlight高亮搜索
@Test
public void testHighlight() {
RestHighLevelClient highClient = getHighClient();
try {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
//指定类型
searchRequest.types(TYPE_NAME);
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//boolQuery搜索方式
//先定义一个MultiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("李四是一个伟大的工程师", "name", "description")
.minimumShouldMatch("50%")
.field("name", 10);
//定义一个boolQuery
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
//定义过虑器
boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(0).lte(30));
searchSourceBuilder.query(boolQueryBuilder);
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name", "age","description"}, new String[]{});
//设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<tag>");
highlightBuilder.postTags("</tag>");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
//highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
searchSourceBuilder.highlighter(highlightBuilder);
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = highClient.search(searchRequest,COMMON_OPTIONS);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
String age = (String) sourceAsMap.get("age");
//取出高亮字段
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();
}
}
System.out.println("ID:" + id + ",name:" + name + ",age:" + age + ",description:" + description);
}
highClient.close();
} catch (IOException ioException) {
// 异常处理。
System.out.println(ioException);
}
}
}
本文详细介绍如何使用Java REST High-Level Client对Elasticsearch进行多种高级查询操作,包括全文检索、精确查询、布尔查询、过滤查询及高亮显示等,通过具体代码示例展示查询效果。
887






