需求:
根据条件(appId,createTIme)筛选出来需要的数据。之后根据userId分组,计算每个用户的最大创建时间。然后筛选出最大时间在一定范围的结果。
java代码实现:
public List<AiUserLoss> getUserUsedList(String appId, Date startDate, Date endDate, Date middleDate) throws Exception {
List<AiUserLoss> list=new ArrayList<>();
SimpleDateFormat si=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime= si.format(startDate);
String endTime=si.format(endDate);
//创建builder
QueryBuilder queryBuilder = QueryBuilders
.boolQuery()
.filter(QueryBuilders.termQuery("appId", appId))
.filter(QueryBuilders.rangeQuery("createTime").gte(startTime).lte(endTime));
TermsAggregationBuilder sign_org_aggs = AggregationBuilders.terms("user_type").field("userId").size(Integer.MAX_VALUE);
// 求出userId聚合的最大创建时间
MaxAggregationBuilder max_time_aggs = AggregationBuilders.max("max_time").field("createTime");
// 筛选出流失时间节点之前的用户数据作为流失用户
Map<String, String> bucketsPathsMap = new HashMap<>();
bucketsPathsMap.put("maxTime","max_time");
// 28800000 es为标准时区。故需加上时间差八小时
BucketSelectorPipelineAggregationBuilder max_bucket_selector = PipelineAggregatorBuilders
.bucketSelector("filter_max_time",bucketsPathsMap,new Script("params.maxTime < "+ (middleDate.getTime() + 28800000) + "L"));
sign_org_aggs.subAggregation(max_time_aggs);
sign_org_aggs.subAggregation(max_bucket_selector);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(BompEsConstant.ES_NLP_TRACE_LOG).withTypes(BompEsConstant.ES_TYPE_AIABILITY)
.withQuery(queryBuilder)
.addAggregation(sign_org_aggs)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
ParsedStringTerms teamAgg1 = (ParsedStringTerms) aggregations.asMap().get("user_type");
List<ParsedStringTerms.ParsedBucket> bucketList = (List<ParsedStringTerms.ParsedBucket>) teamAgg1.getBuckets();
AiUserLoss aiUserLoss = null;
for (ParsedStringTerms.ParsedBucket bucket : bucketList) {
aiUserLoss = new AiUserLoss();
// 结构化地址
String formatAddress = bucket.getKeyAsString();
long count = bucket.getDocCount();
aiUserLoss.setUserId(formatAddress);
aiUserLoss.setCount(count);
list.add(aiUserLoss);
}
return list;
}