##### 聚合统计
// Aggregation 统计 terms 字段每个值和对应值的数量,也可以统计avg 、interval、等
Aggregation aggregation = AggregationBuilders.terms(terms -> terms.field(“terms”));
SearchRequest searchRequest = SearchRequest.of(s -> s.index(“索引name”))
// 查询条件
.query(q -> q.bool(vo.getBoolQuery()))
// 聚合条件 这里 aggregation 也可以通过lambda 自定义 a -> a.histogram(h -> h.field(“price”).interval(50.0))
.aggregations(“aggregations”,aggregation));
SearchResponse searchResponse = elasticsearchClient.search(searchRequest, Map.class);
// 获取统计结果
Aggregate terms = (Aggregate) searchResponse.aggregations().get(“aggregations”);
searchTypeList.lterms().buckets().array().forEach(e -> {
long quantity = e.docCount();
String key= e.key();
});
### 注解方式
上面的方式很繁琐,每增加一个条件都需要我们手动设置条件查询语句,我们可以通过在字段上加上自定义注解的方式 去生成对用的查询条件
主要逻辑如下: 源码放在github ,大家自取 https://github.com/Rfruelu/es-search-api-generator
/**
* 查询模式
*/
public enum EsQueryMode {
TERM,
TERMS,
WILDCARD,
RANGE,
}
/**
* 通用转换
*
* @author LuTshoes
* @version 1.0
*/
public class GeneralConvertHandler implements IConvertHandler {
/\*\*
* 将注解和对象转换为BoolQuery
*
* @param annotation 注解
* @param o 对象
* @return 转换后的BoolQuery
*/
@Override
public BoolQuery convert(Annotation annotation, Object o) {
// 判断注解是否为GeneralConvert类型并且对象不为空
if (annotation instanceof GeneralConvert && Objects.nonNull(o)) {
// 获取注解的key值
String key = ((GeneralConvert) annotation).key();
// 获取注解的查询模式
EsQueryMode mode = ((GeneralConvert) annotation).mode();
// 使用switch语句根据查询模式执行不同的逻辑
switch (mode) {
case TERM:
// 如果查询模式是TERM,则构建BoolQuery对象,添加term查询条件
return QueryBuilders.bool().must(t -> t.term(f -> f.field(key).value(FieldValue.of(JsonData.of(o))))).build();
case TERMS:
// 如果查询模式是TERMS,并且对象是集合类型
if (o instanceof Collection) {
// 将对象转换为集合
Collection<?> collection = (Collection<?>) o;
// 将集合中的每个元素转换为FieldValue对象,并构建成列表
List<FieldValue> fieldValues = collection.stream().map(c -> FieldValue.of(JsonData.of(c))).collect(Collectors.toList());
// 构建BoolQuery对象,添加terms查询条件
return QueryBuilders.bool().must(t -> t.terms(f -> f.field(key).terms(v -> v.value(fieldValues)))).build();
}
break;
case WILDCARD:
// 如果查询模式是WILDCARD,则构建BoolQuery对象,添加wildcard查询条件
return QueryBuilders.bool().must(t -> t.wildcard(f -> f.field(key).value("\*" + o + "\*"))).build();
case RANGE:
// 如果查询模式是RANGE,并且对象是EsRangeObject类型
if (o instanceof EsRangeObject) {
// 将对象转换为EsRangeObject类型
EsRangeObject rangeObject = (EsRangeObject) o;
// 创建RangeQuery.Builder对象,设置查询的字段
RangeQuery.Builder range = QueryBuilders.range().field(key);
// 如果EsRangeObject的from属性不为空,则添加gte查询条件
Optional.ofNullable(rangeObject.getFrom()).ifPresent(from -> range.gte(JsonData.of(from)));
// 如果EsRangeObject的to属性不为空,则添加lte查询条件
Optional.ofNullable(rangeObject.getTo()).ifPresent(to -> range.lte(JsonData.of(to)));
// 构建BoolQuery对象,添加range查询条件
return QueryBuilders.bool().must(range.build().\_toQuery()).build();
}
break;
default:
// 如果查询模式不匹配任何已知模式,则不执行任何操作
break;
}
}
// 如果注解不是GeneralConvert类型或者对象为空,则返回null
return null;
}
}
/**
* @description: 通用转换
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface GeneralConvert {
/\*\*
* 获取键值
*
* @return 返回键值
*/
String key();
/\*\*
* 获取当前ES查询模式
*
* @return 返回当前ES查询模式
*/
EsQueryMode mode();
}
@Data
@Accessors(chain = true)
public class LuTshoes extends AbstractEsConditionReqDto{
@GeneralConvert(key = "term", mode = EsQueryMode.TERM)
private String term;
@GeneralConvert(key = "terms", mode = EsQueryMode.TERMS)
private List<String> terms;
@GeneralConvert(key = "wildcard", mode = EsQueryMode.WILDCARD)
private String wildcard;
@GeneralConvert(key = "rangeObject", mode = EsQueryMode.RANGE)
private EsRangeObject rangeObject;
public static void main(String[] args) throws IllegalAccessException {
LuTshoes luTshoes = new LuTshoes().setTerm("term").setRangeObject(new
EsRangeObject().setFrom("100").setTo("200")).setWildcard("123456").setTerms(List.of("terms","2"));
System.out.println(luTshoes.build());
}
@Override
public BoolQuery build() throws IllegalAccessException {
// 也可以自己定义实现