1 布尔查询
查询十月份手机类型数据:
GET product_index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"type.keyword": {
"value": "手机"
}
}
},
{
"range": {
"createTime": {
"gte": "2022-10-01",
"lte": "2022-10-31"
}
}
}
]
}
},
"size": 10
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ESApplication.class)
@Slf4j
public class BoolSearchTest {
@Autowired
private ElasticsearchClient elasticsearchClient;
private static final String INDEX_NAME = "product_index";
@Test
public void boolSearch() {
boolSearch1("手机", "2022-10-01", "2022-10-31");
boolSearch2("手机", "2022-10-01", "2022-10-31");
}
private void boolSearch2(String type, String startDate, String endDate) {
try {
log.info("SearchTest invoke boolSearch2......");
SearchResponse<ProductPojo> search = elasticsearchClient.search(
req -> req.index(INDEX_NAME).size(10)
.query(q -> q.bool(b -> b.filter(getQueryList(type, startDate, endDate))))
, ProductPojo.class);
for (Hit<ProductPojo> productHit : search.hits().hits()) {
System.out.println(JSON.toJSONString(productHit.source()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private List<Query> getQueryList(String type, String startDate, String endDate) {
List<Query> list = new ArrayList<>();
if (StringUtils.isNotBlank(type)) {
list.add(new Query.Builder().term(t -> t.field("type").value(type)).build());
}
if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
list.add(new Query.Builder().range(r -> r.field("createTime").gte(JsonData.of(startDate)).lte(JsonData.of(endDate))).build());
}
return list;
}
private void boolSearch1(String type, String startDate, String endDate) {
try {
log.info("SearchTest invoke boolSearch1......");
SearchResponse<ProductPojo> search = elasticsearchClient.search(
req -> req.index(INDEX_NAME).size(10).query(q -> q.bool(
b -> {
if (StringUtils.isNotBlank(type)) {
b.filter(t1 -> t1.term(t -> t.field("type").value(type)));
}
if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
b.filter(r1 -> r1.range(r -> r.field("createTime").gte(JsonData.of(startDate)).lte(JsonData.of(endDate))));
}
return b;
}
))
, ProductPojo.class);
for (Hit<ProductPojo> productHit : search.hits().hits()) {
System.out.println(JSON.toJSONString(productHit.source()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2 聚合查询
统计10月手机,不同类型,不同级别,平均价格
GET product_index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"type.keyword": {
"value": "手机"
}
}
},
{
"range": {
"createTime": {
"gte": "2022-10-01",
"lte": "2022-10-31"
}
}
}
]
}
},
"size": 0,
"aggs": {
"tagAggs": {
"terms": {
"field": "tags.keyword",
"size": 10000
},
"aggs": {
"levelAggs": {
"terms": {
"field": "level.keyword",
"size": 10000
},
"aggs": {
"avgAggs": {
"avg": {
"field": "price"
}
}
}
}
}
}
}
}
package com.es;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
import co.elastic.clients.elasticsearch._types.aggregations.StringTermsBucket;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.es.vo.ProductPojo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.platform.commons.util.StringUtils;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ESApplication.class)
@Slf4j
public class AggsSearchTest {
@Autowired
private ElasticsearchClient elasticsearchClient;
private static final String INDEX_NAME = "product_index";
@Test
public void aggsTest() {
aggSearchTest1("手机", "2022-10-01", "2022-10-31");
aggSearchTest2("手机", "2022-10-01", "2022-10-31");
}
private void aggSearchTest2(String type, String startDate, String endDate) {
try {
SearchResponse<ProductPojo> search = elasticsearchClient.search(req ->
req.index(INDEX_NAME).size(0)
.query(q -> q.bool(b -> b.filter(getQueryList(type, startDate, endDate))))
.aggregations(getAggs())
,
ProductPojo.class);
List<StringTermsBucket> tagAggs = search.aggregations().get("tagAggs").sterms().buckets().array();
for (StringTermsBucket tagBucket : tagAggs) {
String tag = tagBucket.key();
List<StringTermsBucket> levelAggs = tagBucket.aggregations().get("levelAggs").sterms().buckets().array();
log.info("tag:{}", tag);
for (StringTermsBucket levelBucket : levelAggs) {
String level = levelBucket.key();
double avgAggs = levelBucket.aggregations().get("avgAggs").avg().value();
log.info("level:{},avgAggs:{}", level, avgAggs);
}
log.info("############################");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public Map<String, Aggregation> getAggs() {
Aggregation.Builder.ContainerBuilder tagAggs = new Aggregation.Builder().terms(t -> t.field("tags.keyword").size(10000));
Aggregation.Builder.ContainerBuilder levelAggs = new Aggregation.Builder().terms(t -> t.field("level.keyword").size(10000));
Aggregation.Builder.ContainerBuilder avgAggs = new Aggregation.Builder().avg(avg -> avg.field("price"));
levelAggs.aggregations("avgAggs", avgAggs.build());
tagAggs.aggregations("levelAggs", levelAggs.build());
Map<String, Aggregation> map = new HashMap<>();
map.put("tagAggs", tagAggs.build());
return map;
}
private void aggSearchTest1(String type, String startDate, String endDate) {
try {
SearchResponse<ProductPojo> search = elasticsearchClient.search(req ->
req.index(INDEX_NAME).size(0)
.query(q -> q.bool(b -> b.filter(getQueryList(type, startDate, endDate))))
.aggregations("tagAggs",
tagAggs -> tagAggs.terms(t -> t.field("tags.keyword").size(10000))
.aggregations("levelAggs", levelAggs -> levelAggs.terms(t -> t.field("level.keyword").size(10000))
.aggregations("avgAggs", avgAggs -> avgAggs.avg(a -> a.field("price")))
)
)
,
ProductPojo.class);
List<StringTermsBucket> tagAggs = search.aggregations().get("tagAggs").sterms().buckets().array();
for (StringTermsBucket tagBucket : tagAggs) {
String tag = tagBucket.key();
List<StringTermsBucket> levelAggs = tagBucket.aggregations().get("levelAggs").sterms().buckets().array();
log.info("tag:{}", tag);
for (StringTermsBucket levelBucket : levelAggs) {
String level = levelBucket.key();
double avgAggs = levelBucket.aggregations().get("avgAggs").avg().value();
log.info("level:{},avgAggs:{}", level, avgAggs);
}
log.info("############################");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private List<Query> getQueryList(String type, String startDate, String endDate) {
List<Query> list = new ArrayList<>();
if (StringUtils.isNotBlank(type)) {
list.add(new Query.Builder().term(t -> t.field("type").value(type)).build());
}
if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
list.add(new Query.Builder().range(r -> r.field("createTime").gte(JsonData.of(startDate)).lte(JsonData.of(endDate))).build());
}
return list;
}
}
3 【桶】聚合查询
统计10月手机,不同类型,不同级别,平均价格最低的手机以及价格
GET product_index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"type.keyword": {
"value": "手机"
}
}
},
{
"range": {
"createTime": {
"gte": "2022-10-01",
"lte": "2022-10-31"
}
}
}
]
}
},
"size": 0,
"aggs": {
"tagAggs": {
"terms": {
"field": "tags.keyword",
"size": 10000
},
"aggs": {
"levelAggs": {
"terms": {
"field": "level.keyword",
"size": 10000
},
"aggs": {
"avgAggs": {
"avg": {
"field": "price"
}
}
}
},
"minAvgLevel": {
"min_bucket": {
"buckets_path": "levelAggs>avgAggs"
}
}
}
}
}
}
package com.es;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
import co.elastic.clients.elasticsearch._types.aggregations.BucketMetricValueAggregate;
import co.elastic.clients.elasticsearch._types.aggregations.StringTermsBucket;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.es.vo.ProductPojo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.platform.commons.util.StringUtils;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ESApplication.class)
@Slf4j
public class BucketAggsSearchTest {
@Autowired
private ElasticsearchClient elasticsearchClient;
private static final String INDEX_NAME = "product_index";
@Test
public void bucketAggsSearchTest() {
searchBucketAggsTest1("手机", "2022-10-01", "2022-10-31");
searchBucketAggsTest2("手机", "2022-10-01", "2022-10-31");
}
private void searchBucketAggsTest2(String type, String startDate, String endDate) {
try {
SearchResponse<ProductPojo> search = elasticsearchClient.search(req -> req
.index(INDEX_NAME).size(0)
.query(q -> q.bool(b -> b.filter(getQueryList(type, startDate, endDate))))
.aggregations(getAggs())
, ProductPojo.class);
List<StringTermsBucket> tagAggs = search.aggregations().get("tagAggs").sterms().buckets().array();
for (StringTermsBucket tagBucket : tagAggs) {
String tag = tagBucket.key();
BucketMetricValueAggregate minAvgLevel = tagBucket.aggregations().get("minAvgLevel").bucketMetricValue();
List<String> levels = minAvgLevel.keys();
double minAvg = minAvgLevel.value();
log.info("tag:{} , levels:{},minAvg:{}", tag, levels, minAvg);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Map<String, Aggregation> getAggs() {
Aggregation.Builder.ContainerBuilder tagAggs = new Aggregation.Builder().terms(t -> t.field("tags.keyword").size(10000));
Aggregation.Builder.ContainerBuilder levelAggs = new Aggregation.Builder().terms(t -> t.field("level.keyword").size(10000));
Aggregation.Builder.ContainerBuilder avgAggs = new Aggregation.Builder().avg(avg -> avg.field("price"));
Aggregation.Builder.ContainerBuilder minBucket = new Aggregation.Builder().minBucket(path -> path.bucketsPath(p -> p.single("levelAggs>avgAggs")));
levelAggs.aggregations("avgAggs", avgAggs.build());
tagAggs.aggregations("levelAggs", levelAggs.build());
tagAggs.aggregations("minAvgLevel", minBucket.build());
Map<String, Aggregation> map = new HashMap<>();
map.put("tagAggs", tagAggs.build());
return map;
}
private void searchBucketAggsTest1(String type, String startDate, String endDate) {
try {
SearchResponse<ProductPojo> search = elasticsearchClient.search(req -> req
.index(INDEX_NAME).size(0)
.query(q -> q.bool(b -> b.filter(getQueryList(type, startDate, endDate))))
.aggregations("tagAggs", tagAggs -> tagAggs.terms(t -> t.field("tags.keyword").size(10000))
.aggregations("levelAggs", levelAggs -> levelAggs.terms(t -> t.field("level.keyword").size(10000))
.aggregations("avgAggs", avgAggs -> avgAggs.avg(a -> a.field("price"))))
.aggregations("minAvgLevel", minAvgLevel -> minAvgLevel.minBucket(min -> min.bucketsPath(p -> p.single("levelAggs>avgAggs"))))
)
, ProductPojo.class);
List<StringTermsBucket> tagAggs = search.aggregations().get("tagAggs").sterms().buckets().array();
for (StringTermsBucket tagBucket : tagAggs) {
String tag = tagBucket.key();
BucketMetricValueAggregate minAvgLevel = tagBucket.aggregations().get("minAvgLevel").bucketMetricValue();
List<String> levels = minAvgLevel.keys();
double minAvg = minAvgLevel.value();
log.info("tag:{} , levels:{},minAvg:{}", tag, levels, minAvg);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private List<Query> getQueryList(String type, String startDate, String endDate) {
List<Query> list = new ArrayList<>();
if (StringUtils.isNotBlank(type)) {
list.add(new Query.Builder().term(t -> t.field("type").value(type)).build());
}
if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
list.add(new Query.Builder().range(r -> r.field("createTime").gte(JsonData.of(startDate)).lte(JsonData.of(endDate))).build());
}
return list;
}
}