前言
本节主要实现条件查询中的组合查询,范围查询
实现
组合查询
在ES中,组合查询和范围查询是常见的查询类型。
组合查询: 在Elasticsearch中,可以使用bool查询来组合多个查询条件。bool查询允许使用must、should、must_not和filter子句来组合其他查询:
GET _search
{
"query": {
"bool": {
"must": [
{ "match": { "field1": "value1" } },
{ "match": { "field2": "value2" } }
]
}
}
}
这里,Elasticsearch将返回同时满足field1为value1和field2为value2的文档。
编写组合查询
ESTest_Doc_Cond_Query_Com.java
package com.zwy.es;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
public class ESTest_Doc_Cond_Query_Com {
public static void main(String[] args) throws IOException {
//
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 组合查询数据
SearchRequest request = new SearchRequest();
request.indices("users");
SearchSourceBuilder builer = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "男"));
// boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex", "女"));
builer.query(boolQueryBuilder);
request.source(builer);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits()); // 打印
System.out.println(response.getTook()); // 打印
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
// 关闭ES客户端
esClient.close();
}
}
代码概要如下:
创建一个SearchRequest对象,指定要搜索的索引为"users"。
SearchRequest request = new SearchRequest();
request.indices("users");
创建一个SearchSourceBuilder对象,这个对象将用于构建查询条件。
SearchSourceBuilder builer = new SearchSourceBuilder();
创建一个BoolQueryBuilder对象,用于组合多个查询条件。在这个例子中,我们使用了两个must子句,表示文档必须同时满足这两个条件才能被返回。
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "男"));
将BoolQueryBuilder添加到SearchSourceBuilder中。
builer.query(boolQueryBuilder);
将构建好的SearchSourceBuilder设置到SearchRequest对象中。
request.source(builer);
使用RestHighLevelClient执行搜索请求,并获取响应。
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
从响应中获取搜索命中数(即匹配查询条件的文档数量)和查询所花费的时间。
结果查询"users"索引中年龄为30且性别为"男"的文档,并打印出查询结果的数量、查询耗时及每个匹配文档的源数据。
范围查询
范围查询在Elasticsearch中是通过range实现的,可以指定一个字段的值应该在某个范围内,或者特定于某个边界。
示例查询age字段在25到30之间的文档:
GET _search
{
"query": {
"range": {
"age": {
"gte": 25,
"lte": 30
}
}
}
}
这里返回所有age字段值大于等于25且小于等于30的结果
两种查询可以组合,如,查找age在25到30之间且field1为value1和field2为value2的文档:
GET _search
{
"query": {
"bool": {
"must": [
{ "match": { "field1": "value1" } },
{ "match": { "field2": "value2" } }
],
"filter": {
"range": {
"age": {
"gte": 25,
"lte": 30
}
}
}
}
}
}
在这里,must子句用于匹配文本字段,而filter子句中的range查询则用于过滤出年龄在指定范围内的文档,由于filter子句不会影响相关性评分,所以通常用于这样的过滤条件。
编写范围查询
ESTest_Doc_Cond_Query_Range.java
package com.zwy.es;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
public class ESTest_Doc_Cond_Query_Range {
public static void main(String[] args) throws IOException {
//
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 范围查询数据
SearchRequest request = new SearchRequest();
request.indices("users");
SearchSourceBuilder builer = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age"); // 设定年龄范围
rangeQuery.gte(30);
rangeQuery.lte(40);
builer.query(rangeQuery);
request.source(builer);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits()); // 打印
System.out.println(response.getTook()); // 打印
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
// 关闭ES客户端
esClient.close();
}
}
代码概要如下:
创建一个RestHighLevelClient实例
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
``
创建SearchRequest对象,指定要搜索的索引为"users"。
```java
SearchRequest request = new SearchRequest();
request.indices("users");
创建SearchSourceBuilder对象,这个对象将用于构建查询条件。
SearchSourceBuilder builer = new SearchSourceBuilder();
创建RangeQueryBuilder对象,用于指定年龄字段的范围查询,我们设置了年龄大于等于30且小于等于40。
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age"); // 设定年龄范围
rangeQuery.gte(30); // 大于等于30
rangeQuery.lte(40); // 小于等于40
将RangeQueryBuilder添加到SearchSourceBuilder中。
builer.query(rangeQuery);
将构建好的SearchSourceBuilder设置到SearchRequest对象中。
request.source(builer);
使用RestHighLevelClient执行搜索请求,并获取响应。
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
从响应中获取搜索命中数(即匹配查询条件的文档数量)和查询所花费的时间。
System.out.println(hits.getTotalHits()); // 打印总命中数
System.out.println(response.getTook()); // 打印查询所花费的时间
遍历所有命中结果,打印每个文档的源数据。
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
这里我们查询"users"索引中年龄在30到40之间的文档,并打印出查询结果的数量、查询耗时及每个匹配文档的源数据。
文件结构
文件结构如下:
运行
运行ESTest_Doc_Cond_Query_Com.java,结果如下:
运行ESTest_Doc_Cond_Query_Range.java,结果如下: