JAVA mongodb mongoTemplate 多字段多条件 分组统计 时间转换 并且返回想要的值

最近在做订单汇总、商品汇总等等查询,mongo 以前用的不多,最近研究的一点东西,记录一下

 

javabean 

订单详情明细类(包含商品信息)

@Data
@Document(collection = "order_info")
public class OrderMongoEntity extends BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @Id
    private String id;

    /**
     * 门店 id
     */
    @Field("sid")
    private Integer sid;
    
    //***省略字段

    /**
     * 创建时间
     */
    @Field("create_time")
    private Long createTime;

    //***省略字段

    /**
     * 订单状态
     */
    @Field("order_status")
    private OrderStatusEnum orderStatus;

    /**
     * 品列表
     */
    @Field("products")
    private List products;

    @Data
    public static class ProductEntity implements Serializable {
        private int pid;
        private String productsDetail;
        private int num;
        private BigDecimal price;

        public  T getT(Class tClass) {
            return JSON.parseObject(productsDetail, tClass);
        }
    }

}

聚合后返回的类

@Data
@EqualsAndHashCode(callSuper = true)
public class OrderAggregateStatisticsEntity extends BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    //因为分组是多条件 这个地方会有很多数据 用 Object 接收就可以  这个数据不需要用
    private Object id;

    private long count;

    private int sid;

    private int pid;

    private String day;

}

mongoTemplate 查询

//查询条件,个人习惯这样写,请勿对比
        List where=new ArrayList<>();
        where.add(Criteria.where("create_time").gte(start).lt(end));
//        where.add(Criteria.where("order_status").is(OrderStatusEnum.Complete));
// 子集合查询
// 因为 operations.add(Aggregation.unwind("products"))的存在  可以直接写 products.pid 
// 如果没有unwind 需要 elemMatch 没有测试 所以这里不多说
        where.add(Criteria.where("products.pid").is(18955));

        List operations = new ArrayList<>();
        operations.add(Aggregation.match(new Criteria().andOperator(where.toArray(Criteria[]::new))));  
    //把所有需要查询的字段在这里列出来  注意这里的字段是 javabean 的字段
    // createTime 转换成 2020-12-12 并且加了 8个小时 
    // as("day") 是给字段起一个别名
        operations.add(Aggregation.project( "sid", "products","createTime")
                .andExpression("{$dateToString: {date: { $add: {'$create_time', [0]} }, format: '%Y-%m-%d'}}", new Date(0)).as("day"));
        //unwind 我的理解是 list变成单条返回
        //去除 list
        operations.add(Aggregation.unwind("products"));
        //需要分组的字段名
        List group = new ArrayList<>();
        group.add("day");
        group.add("sid");
        group.add("products.pid");
        //      group 分组
        //   first("day").as("day") first 把第一个 day 的值取出来重名 as 成新字段 day 
        //first("products.pid").as("pid") 同样的意思 只是这个是子集合的
operations.add(Aggregation.group(group.toArray(String[]::new)).sum("products.num").as("count")
                .first("day").as("day")
                .first("products.pid").as("pid")
                .first("sid").as("sid"));
        // 需要返回的字段名字 这里是 as 后的名字
        operations.add(Aggregation.project( "pid","day","sid","count"));

    // 正常排序
        operations.add(Aggregation.sort(Sort.by(Sort.Direction.DESC, "count")));
    //查询       
 AggregationResults Results = mongoTemplate.aggregate(Aggregation.newAggregation(operations), OrderMongoEntity.class, OrderAggregateStatisticsEntity.class);

        //输出
        System.out.println(">>>>>" + JSON.toJSONString(Results.getMappedResults()));

 

 

欢迎讨论谢谢!!!

 

参考1 https://blog.csdn.net/weixin_46114677/article/details/109805644

参考2 https://blog.csdn.net/pengjunlee/article/details/106992249

参考3 https://blog.csdn.net/hotdust/article/details/52605990

你可能感兴趣的:(springboot,日常记录,服务崛起之路,java踩坑之路)