需求:使用mongoTemplate查询集合UserTrade数据,1.查询条件为assetNoList(字段assetNo集合)、idList(_id集合)及state=1。2.过滤重复数据,只按assetNo过滤,3.考虑assetNoList或idList有可能为空,4.增加需求,UserTrade集合有十几个很多字段,而我只需要返回_id、assetNo、userId、templateId、templateName、remarks、tradeNo这几个字段即可。5.对于重复数据行,point返回集合points,其他条件不变
// 1. 动态构建查询条件(处理空列表)
Criteria criteria = Criteria.where("state").is(Constant.DEL_FLAG_NORMAL);
if (idList != null && !idList.isEmpty() && !idList.stream().allMatch(Objects::isNull)) {
criteria = criteria.and("_id").in(idList);
} else if (assetNoList != null && !assetNoList.isEmpty()) {
criteria = criteria.and("assetNo").in(assetNoList);
}
// 2. 聚合框架实现去重和字段投影
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.group("assetNo")
.first("_id").as("originalId") // 保留原始_id
.first("assetNo").as("assetNo")
.first("userId").as("userId")
.first("templateId").as("templateId")
.first("templateName").as("templateName")
.first("remarks").as("remarks")
.first("tradeNo").as("tradeNo")
.push("$point").as("points"),
Aggregation.project("assetNo", "userId", "templateId", "templateName", "remarks", "tradeNo")
.and("originalId").as("_id") // 恢复原始_id
.andInclude("points") // 如果需要points
);
// 3. 执行聚合查询并映射结果
AggregationResultsresults = mongoTemplate.aggregate(aggregation,"userTrade",UserTrade.class);
Listlist = results.getMappedResults();
if(ListUtils.isEmpty(list)){
continue;
}
UserTrade实体类
@Data
@Builder
public class UserTrade {
/**
* 主键id
*/
private String _id;
/**
* 交易编号
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long tradeNo;
/**
* 资产编号
*/
private Long assetNo;
/**
* 员工用户id
*/
private String userId;
/**
* 登录账号
*/
private String username;
/**
* 手机号
*/
private String phone;
/**
* 姓名
*/
private String name;
/**
* 子模板id
*/
private Long templateId;
/**
* 子模板名称
*/
private String templateName;
/**
* 充值金额
*/
private BigDecimal point;
/**
* 剩余金额
*/
private BigDecimal surplusPoint;
/**
* 撤回状态(0-已撤回,1-未撤回)
*/
private Integer state;
private String stateName;
/**
* 过期时间
*/
private Date expireTime;
/**
* 交易时间
*/
private Date gmtCreate;
/**
* 交易备注
*/
private String remarks;
/**
* 冻结状态
*/
private Integer freezeState;
/**
* 冻结状态名称
*/
private String freezeStateName;
/**
* 签名领取状态 0 未领取 1 已领取
*/
private Integer collectState;
private String collectStateValue;
/**
* 截止领取时间
*/
private Date collectExpireTime;
/**
* 领取时间
*/
private Date collectTime;
/**
* 分配编号(激活卡专有)
*/
private String allotNumber;
/**
* 支出时间
*/
private Date paidTime;
/**
* 激活卡卡号
*/
private String assetAccount;
/**
* 结算类型
*/
private Integer settType;
/**
* 结算类型 1.先结 2.后结
*/
private String settTypeName;
/**
* 转入转出操作的
* 原始批次编号(reTradeNo,转入记录则为从哪个批次转入的交易编号;
* 转出记录则从自己的哪个批次转出的交易编号)
*/
private String reTradeNo;
/**
* 目标/来源资产编号(reAssetNo,转入=从哪来,转出=到哪去)
*/
private Long reAssetNo;
/*************************批量撤回特有字段**************************/
private Listpoints;
}
欢迎关注公众号