需求:使用mongoTemplate查询集合UserTrade,过滤重复数据
需求:使用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;
}
评论功能已关闭