elasticsearch—API文档高级查询
/**
* 查询全部文档数据
*/
@Test
public void queryAllIndex() throws IOException {
//创建es客户端 对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有数据
sourceBuilder.query(QueryBuilders.matchAllQuery());
//创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理查询结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es客户端
esClient.close();
}
took:58ms
timeout:false
total:2 hits
maxScore:1.0
输出记录:》》》》》》》》》
{"brand":"iPhone","model":"iPhone 13","price":5999}
{"brand":"华为","model":"HUAWEI P50","price":4488}
关键字查询,需要注意中文分词及keyword
的使用
/**
* term查询,关键字查询
*/
@Test
public void termQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("price", "4488"));
//term处理字符串时,由于es默认分词器会将每一个中文都进行了分割(存到es中的数据,保存的是单个的中文),直接搜一个整词是无法搜索到的
//需要加keyword
//sourceBuilder.query(QueryBuilders.termQuery("brand.keyword", "华为"));
//创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
}
took:4ms
timeout:false
total:1 hits
maxScore:0.6931471
查询记录:》》》》》》》》》
{"brand":"华为","model":"HUAWEI P50","price":4488}
/**
* 分页查询
*/
@Test
public void pageQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体对象
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
//分页条件设置
//当前页索引
sourceBuilder.from(0);
//每页显示多少条
sourceBuilder.size(1);
//创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求 获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理查询结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxSource:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit ->{
System.out.println(hit.getSourceAsString());
});
//关闭es客户端
esClient.close();
}
took:3ms
timeout:false
total:2 hits
maxSource:1.0
查询记录:》》》》》》》》》
{"brand":"iPhone","model":"iPhone 13","price":5999}
/**
* 排序查询
* Text字段不支持聚合,需要加keyword实现
* 也可以使Text类型启动fielddata属性,但是不推荐,field data和其缓存存储在堆中,这使得它们的计算成本很高
*/
@Test
public void sortQuery() throws IOException {
//创建es客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
//排序 按price降序
sourceBuilder.sort("price.keyword", SortOrder.DESC);
//创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理查询结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxSource:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
}
took:66ms
timeout:false
total:2 hits
maxSource:NaN
查询记录:》》》》》》》》》
{"brand":"iPhone","model":"iPhone 13","price":5999}
{"brand":"华为","model":"HUAWEI P50","price":4488}
类似于:
select brand, model from tb
只查询出需要的字段
/**
* 过滤字段查询
* 类似于select a, b from tb,只查询需要的字段
*/
@Test
public void filterFieldQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
//查询字段过滤
String[] excludes = {"brand"}; //排除字段
String[] includes = {"price", "model"}; //包含字段
sourceBuilder.fetchSource(includes, excludes);
//创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es客户端
esClient.close();
}
took:6ms
timeout:false
total:2 hits
maxScore:1.0
查询记录:》》》》》》》》》
{"price":5999,"model":"iPhone 13"}
{"price":4488,"model":"HUAWEI P50"}
/**
* bool查询
*/
@Test
public void boolQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//必须包含
boolQueryBuilder.must(QueryBuilders.matchQuery("brand", "华为"));
//一定不含
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("model", "iPhone"));
//可能包含
boolQueryBuilder.should(QueryBuilders.matchQuery("price", "2988"));
sourceBuilder.query(boolQueryBuilder);
//构建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es
esClient.close();
}
took:3ms
timeout:false
total:3 hits
maxScore:2.3642673
查询记录:》》》》》》》》》
{"brand":"华为","model":"华为荣耀2","price":2988}
{"brand":"华为","model":"HUAWEIP40","price":4988}
{"brand":"华为","model":"华为荣耀1","price":1988}
/**
* 范围查询
*/
@Test
public void rangeQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
//大于等于
rangeQueryBuilder.gte("1999");
//小于等于
rangeQueryBuilder.lte("5999");
sourceBuilder.query(rangeQueryBuilder);
//创建搜索查询对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es
esClient.close();
}
took:16ms
timeout:false
total:3 hits
maxScore:1.0
查询记录:》》》》》》》》》
{"brand":"iPhone","model":"iPhone11","price":5999}
{"brand":"华为","model":"HUAWEIP40","price":4988}
{"brand":"华为","model":"华为荣耀2","price":2988}
fuzziness
设置参数的最大编辑次数,可以理解为,把查询条件输入错误了,通过fuzziness
编辑指正。
比如:将“荣威”指正为“荣耀”
/**
* 模糊查询
*/
@Test
public void fuzzyQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//Fuzziness是对查询字符串的编辑次数,可以理解为我们要搜索“荣耀”,但输入的是“荣威”,
//所以需要把“荣威”进行修改成“荣耀”,这样可以达到我们所想要查询的,但修改的次数也是有限制的
//Fuzziness有具体的属性说明
sourceBuilder.query(QueryBuilders.fuzzyQuery("model", "荣威").fuzziness(Fuzziness.ONE));
//创建查询请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es
client.close();
}
took:2ms
timeout:false
total:2 hits
maxScore:0.0
查询记录:》》》》》》》》》
{"brand":"华为","model":"华为荣耀1","price":1988}
{"brand":"华为","model":"华为荣耀2","price":2988}
/**
* 高亮查询
*/
@Test
public void highLightQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式:高亮查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brand.keyword", "华为");
sourceBuilder.query(termQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
//设置前缀标签
highlightBuilder.preTags("");
//设置后缀标签
highlightBuilder.postTags("");
//设置高亮字段
//highlightBuilder.field("brand");
highlightBuilder.field("brand.keyword");
//设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
//创建查询请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
hits.forEach(hit -> {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
//打印高亮结果
Map<String, HighlightField> highlightFieldMap = hit.getHighlightFields();
System.out.println(highlightFieldMap);
});
//关闭es客户端
esClient.close();
}
took:3ms
timeout:false
total:3 hits
maxScore:0.53899646
查询记录:》》》》》》》》》
{"brand":"华为","model":"HUAWEIP40","price":4988}
{brand.keyword=[brand.keyword], fragments[[<font color='red'>华为</font>]]}
{"brand":"华为","model":"华为荣耀1","price":1988}
{brand.keyword=[brand.keyword], fragments[[<font color='red'>华为</font>]]}
{"brand":"华为","model":"华为荣耀2","price":2988}
{brand.keyword=[brand.keyword], fragments[[<font color='red'>华为</font>]]}
/**
* 聚合查询-最大值
*/
@Test
public void maxQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//maxPrice:聚合查询名称,自定义 price:聚合的字段条件
sourceBuilder.aggregation(AggregationBuilders.max("maxPrice").field("price"));
//创建查询对象请求
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
Aggregations aggregations = response.getAggregations();
ParsedMax parsedMax = aggregations.get("maxPrice");
System.out.println(parsedMax.getValue());
// ParsedTerms parsedTerms = aggregations.get("maxPrice");
// List extends Terms.Bucket> buckets = parsedTerms.getBuckets();
// buckets.forEach(bucket -> {
// System.out.println(bucket.getKey() + " : " + bucket.getDocCount());
// });
//关闭es客户端对象
client.close();
}
took:426ms
timeout:false
total:5 hits
maxScore:1.0
查询记录:》》》》》》》》》
5999.0
/**
* 最小值
*/
@Test
public void minQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//minPrice:聚合查询名称,自定义 price:聚合的字段条件
sourceBuilder.aggregation(AggregationBuilders.min("minPrice").field("price"));
//创建查询对象请求
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应对象
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//处理响应结果
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
Aggregations aggregations = response.getAggregations();
ParsedMin parsedMin = aggregations.get("minPrice");
System.out.println(parsedMin.getValue());
//关闭es客户端对象
esClient.close();
}
took:2ms
timeout:false
total:5 hits
maxScore:1.0
查询记录:》》》》》》》》》
1988.0
/**
* 求和
*/
@Test
public void sumQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//sumPrice:聚合查询名称,自定义 price:聚合的字段条件
sourceBuilder.aggregation(AggregationBuilders.sum("sumPrice").field("price"));
//创建查询对象请求
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
Aggregations aggregations = response.getAggregations();
ParsedSum parsedSum = aggregations.get("sumPrice");
System.out.println(parsedSum.getValue());
//关闭es客户端对象
client.close();
}
took:177ms
timeout:false
total:5 hits
maxScore:1.0
查询记录:》》》》》》》》》
21962.0
/**
* 平均值
*/
@Test
public void avgQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//avgPrice:聚合查询名称,自定义 price:聚合的字段条件
sourceBuilder.aggregation(AggregationBuilders.avg("avgPrice").field("price"));
//创建查询请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理响应结果
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("maxScore:" + hits.getMaxScore());
System.out.println("查询记录:》》》》》》》》》");
Aggregations aggregations = response.getAggregations();
ParsedAvg parsedAvg = aggregations.get("avgPrice");
System.out.println(parsedAvg.getValue());
//关闭es客户端对象
client.close();
}
took:5ms
timeout:false
total:5 hits
maxScore:1.0
查询记录:》》》》》》》》》
4392.4
/**
* 分组
*/
@Test
public void groupByQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("groupByBrand").field("brand"));
//创建查询请求对象
SearchRequest request = new SearchRequest();
request.indices("phone");
request.source(sourceBuilder);
//发送请求,获取响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//打印响应结果
System.out.println(response);
// SearchHits hits = response.getHits();
// System.out.println("查询记录:》》》》》》》》》");
// hits.forEach(hit -> {
// String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// });
//关闭es客户端
client.close();
}
多条件:就是把多个查询的QueryBuilder
组合到一起,实现多个查询条件的builder联合查询
多查询:就是按批次查询,查询1、查询2…使用一个request
进行请求
/**
* 多查询及多条件
* @throws IOException
*/
@Test
public void multiQuery() throws IOException {
//创建es客户端对象
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
//构建多查询
MultiSearchRequest request = new MultiSearchRequest();
//构建查询请求1
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeBuilder = QueryBuilders.rangeQuery("price");
rangeBuilder.gte("1999");
rangeBuilder.lte("3999");
//使用filter把多个builder组合一起
boolQueryBuilder.must(QueryBuilders.matchQuery("brand", "华为")).filter(rangeBuilder);
sourceBuilder.query(boolQueryBuilder);
SearchRequest firstRequest = new SearchRequest();
firstRequest.indices("phone");
firstRequest.source(sourceBuilder);
request.add(firstRequest);
//构建查询请求2
sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
rangeQueryBuilder.gte("1999");
rangeQueryBuilder.lte("9999");
sourceBuilder.query(rangeQueryBuilder);
SearchRequest secondRequest = new SearchRequest();
secondRequest.indices("phone");
secondRequest.source(sourceBuilder);
request.add(secondRequest);
//发送请求,获取响应结果
MultiSearchResponse response = esClient.msearch(request, RequestOptions.DEFAULT);
MultiSearchResponse.Item firstResp = response.getResponses()[0]; //第一个查询结果
MultiSearchResponse.Item secondResp = response.getResponses()[1]; //第二个查询结果
//处理响应结果
SearchHits hits1 = firstResp.getResponse().getHits();
System.out.println("total:" + hits1.getTotalHits());
System.out.println("查询记录:》》》》》》》》》");
hits1.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
SearchHits hits2 = secondResp.getResponse().getHits();
System.out.println("total:" + hits2.getTotalHits());
System.out.println("查询记录:》》》》》》》》》");
hits2.forEach(hit -> {
System.out.println(hit.getSourceAsString());
});
//关闭es
esClient.close();
}