mongodb在Java中条件分组聚合查询并且分页(时间戳,按日期分组,年月日...)
废话不多说,先看效果图:
- SQL查询结果示例:

- 多种查询结果示例:

原SQL:
db.getCollection("hbdd_order").aggregate([{// 把时间戳格式化$addFields: {orderDate: {"$dateToString": {"format": "%Y-%m-%d","date": {"$toDate": "$hzdd_order_addtime"}}}}},{$match: {// 筛选条件hzdd_order_addtime: {$gte: 1722441600000,$lt: 1725120000000}}},{// 按格式过的时间分组$group: {"_id": "$orderDate",paidAmount: {$sum: { // 统计$cond: [{ // 条件类似if true =1 else =0$eq: ["$hzdd_order_ispay", 1]}, "$hzdd_order_amount", 0]}},paidCount: {$sum: {$cond: [{$eq: ["$hzdd_order_ispay", 1]}, 1, 0]}},unpaidAmount: {$sum: {$cond: [{$eq: ["$hzdd_order_ispay", 0]}, "$hzdd_order_amount", 0]}},unpaidCount: {$sum: {$cond: [{$eq: ["$hzdd_order_ispay", 0]}, 1, 0]}}}},{$project: {date: "$_id",paidAmount: 1,paidCount: 1,unpaidAmount: 1,unpaidCount: 1}},{$sort: { // 排序date: 1}}
]);
Java语句:
代码中多了些内容,但是和SQL语句大差不差
(懒得替换类名,大家看到陌生的类就是自己建的)
import com.mongodb.client.result.UpdateResult;
import jodd.util.StringUtil;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;public Page<OrderStatVo> orderStatistical(OrderStatQuery query) { Pageable pageable = PageRequest.of(query.getPageNum() - 1, query.getPageSize());MongoTemplate mongoTemplate = mongoFactory.mongoTemplate(OrderConstants.ORDER_DB);// 时间筛选Long startTime = query.getStartTime();Long endTime = query.getEndTime();// 区分 1年,2月,3日int type = query.getType();// 按商家idString shopId = query.getShopId();// 按code筛选Integer areaCode = query.getAreaCode();Integer provinceCode = query.getProvinceCode();Integer cityCode = query.getCityCode();Integer countyCode = query.getCountyCode();// 基础匹配条件:按年初和年末 时间戳Criteria baseCriteria = new Criteria();// 额外的筛选条件List<Criteria> additionalCriteria = new ArrayList<>();if (startTime != null && endTime != null) {additionalCriteria.add(Criteria.where("hzdd_order_addtime").gte(startTime).lt(endTime));}if (StringUtil.isNotEmpty(shopId)) {additionalCriteria.add(Criteria.where("hzdd_order_sjid").is(shopId));}if (areaCode != null && areaCode != 0) {additionalCriteria.add(Criteria.where("hzdd_order_area_code").is(areaCode));}if (provinceCode != null && provinceCode != 0) {additionalCriteria.add(Criteria.where("hzdd_order_province_code").is(provinceCode));}if (cityCode != null && cityCode != 0) {additionalCriteria.add(Criteria.where("hzdd_order_city_code").is(cityCode));}if (countyCode != null && countyCode != 0) {additionalCriteria.add(Criteria.where("hzdd_order_county_code").is(countyCode));}// 合并所有条件if (!additionalCriteria.isEmpty()) {baseCriteria.andOperator(additionalCriteria.toArray(new Criteria[0]));}// 构建匹配操作MatchOperation matchOperation = Aggregation.match(baseCriteria);// 添加字段操作,将 Unix 时间戳转换为日期字符串String expression = switch (type) {case 1 -> "{$dateToString: { format: '%Y', date: { $toDate: '$hzdd_order_addtime' }}}";case 2 -> "{$dateToString: { format: '%Y-%m', date: { $toDate: '$hzdd_order_addtime' }}}";case 3 -> "{$dateToString: { format: '%Y-%m-%d', date: { $toDate: '$hzdd_order_addtime' }}}";default -> "{$dateToString: { format: '%Y-%m-%d', date: { $toDate: '$hzdd_order_addtime' }}}";};AddFieldsOperation addFieldsOperation = Aggregation.addFields().addField("orderDate").withValueOfExpression(expression).build();// 分组操作GroupOperation groupOperation = Aggregation.group("orderDate").sum(ConditionalOperators.Cond.when(Criteria.where("hzdd_order_ispay").is(1)).then("$hzdd_order_amount").otherwise(0)).as("paidAmount").sum(ConditionalOperators.Cond.when(Criteria.where("hzdd_order_ispay").is(1)).then(1).otherwise(0)).as("paidCount").sum(ConditionalOperators.Cond.when(Criteria.where("hzdd_order_ispay").is(0)).then("$hzdd_order_amount").otherwise(0)).as("unpaidAmount").sum(ConditionalOperators.Cond.when(Criteria.where("hzdd_order_ispay").is(0)).then(1).otherwise(0)).as("unpaidCount");// 投影操作ProjectionOperation projectionOperation = Aggregation.project().and("_id").as("date").andInclude("paidAmount", "paidCount", "unpaidAmount", "unpaidCount");// 排序操作SortOperation sortOperation = Aggregation.sort(Sort.Direction.ASC, "date");// 分页操作SkipOperation skipOperation = Aggregation.skip((long) pageable.getPageNumber() * pageable.getPageSize());LimitOperation limitOperation = Aggregation.limit(pageable.getPageSize());// 构建不包含分页的聚合查询以获取总条数Aggregation countAggregation = Aggregation.newAggregation(matchOperation,addFieldsOperation,groupOperation,Aggregation.group("orderDate").count().as("totalCount"), // 添加计数操作Aggregation.project("totalCount").andExclude("_id") // 只包含 totalCount 字段);// 执行聚合查询以获取总条数AggregationResults<Document> totalCountResults = mongoTemplate.aggregate(countAggregation, "hbdd_order", Document.class);Document document = totalCountResults.getMappedResults().stream().findFirst().orElse(null);int total = document != null ? (int) document.get("totalCount") : 0;// 构建包含分页的聚合查询Aggregation aggregation = Aggregation.newAggregation(matchOperation,addFieldsOperation,groupOperation,projectionOperation,sortOperation,skipOperation,limitOperation);// 第二个参数是文档名(表名),第三个参数是接收的类,字段对应上面代码中的as别名字段AggregationResults<OrderStatVo> results = mongoTemplate.aggregate(aggregation, "hbdd_order", OrderStatVo.class);List<OrderStatVo> everyDayOrderStats = results.getMappedResults();// 分页操作return new PageImpl<>(everyDayOrderStats, pageable, total);}
** OrderStatQuery 类就不展示了,就是传值进来的筛选条件 **
OrderStatVo类
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;@Data
@Schema(description = "订单统计")
public class OrderStatVo {@Schema(description = "周期")private String date;@Schema(description = "已支付金额")private Double paidAmount;@Schema(description = "已支付订单数")private Long paidCount;@Schema(description = "未支付金额")private Double unpaidAmount;@Schema(description = "未支付订单数")private Long unpaidCount;}
Java中使用mongoDB小技巧:
配置文件中加上下面这行,可以打印出mongo的SQL语句
logging:level:org.springframework.data.mongodb.core.MongoTemplate: DEBUG
相关文章:
mongodb在Java中条件分组聚合查询并且分页(时间戳,按日期分组,年月日...)
废话不多说,先看效果图: SQL查询结果示例: 多种查询结果示例: 原SQL: db.getCollection("hbdd_order").aggregate([{// 把时间戳格式化$addFields: {orderDate: {"$dateToString": {"for…...
怎么样处理浮毛快捷又高效?霍尼韦尔、希喂、米家宠物空气净化器实测对比
掉毛多?掉毛快?猫毛满天飞对身体有危害吗?多猫家庭经验分享篇: 一个很有趣的现象,很多人在养猫、养狗后耐心都变得更好了。养狗每天得遛,养猫出门前得除毛,日复一日的重复磨练了极好的耐心。我家…...
什么是WebGL技术?有什么特点?应用领域有哪些?
WebGL(Web Graphics Library)技术是一种在Web浏览器中渲染交互式3D和2D图形的JavaScript API。以下是对WebGL技术的详细解析: 一、定义与起源 定义: WebGL全称Web Graphics Library,即网络图形库,它允许…...
500W逆变器(一)
EG8015_24V_500W 这款逆变器是基于 EG8015 SPWM 专用芯片而设计的方案。其额定的输出功率为 500 瓦, 最大输出功率为 600 瓦,输出电压为 220V10%,输出频率为 50Hz0.1Hz,额定输出电流为 2.3 安培。 穿越机降落的时候不要垂直降落,要…...
ubuntu 22.04 编译安装新内核
1、普通用户登录系统 查看当前内核版本 $ uname -r 5.15.0-118-generic 2、下载内核源码 www.kernel.org 用户home目录新建子目录linux,下载并解压 linux-5.15.165.tar.xz 3、创建起始的配置文件.config Configuration targets (见linux kernel i…...
Linux 文件权限与属性管理
概述 Linux 系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux 对不同用户访问同一文件(包括目录文件)的权限做了详细的规定。 文件属性查看 在 Linux 中࿰…...
Django学习实战篇三(适合略有基础的新手小白学习)(从0开发项目)
前言: 在上一章中,我们对Django的Model层有了比较全面的认识,本章就来配置Django自带的admin。这里需要认识到,Django的Model层是很重要的一环,无论是对于框架本身还是对于基于Django框架开发的大多数系统而言。因为一…...
【SPIE独立出版,连续2届稳定EI检索!】2024年第三届信息学,网络与计算技术国际学术会议(ICINC2024,10月25-27)
2024年第三届信息学,网络与计算技术国际学术会议(ICINC2024)将于2024年10月25-27日于中国郑州召开。 会议将围绕信息技术与通信,网络与计算技术等在相关领域中的最新研究成果,为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者…...
.NET/C#⾯试题汇总系列:基础语法
1. 字符串中string strnull和string str""和string strstring.Empty的区别? string str null;:这种方式声明了一个字符串变量str,并将其初始化为null。这意味着str不指向任何实际的字符串对象。如果你试图访问str的属性或方法&…...
【论文阅读】SwiftTheft: A Time-Efficient Model Extraction Attack Framework(2024)
完整标题 SwiftTheft: A Time-Efficient Model Extraction Attack Framework Against Cloud-Based Deep Neural Networks 摘要 With the rise of artificial intelligence(人工智能) and cloud computing(云计算), machine-learning-as-a-service platforms(机器学习即…...
springcloud间通信的方式
在 Spring Cloud 中,主要有以下几种通信方式: 一、基于 HTTP 的 RESTful API 工作原理: 这是一种常见的通信方式,各个微服务通过发送 HTTP 请求来相互调用。服务提供者暴露 RESTful API 接口,服务消费者通过 HTTP 客户…...
【C++ Qt day9】
2、将day1做的登录界面升级优化【资源文件的添加】 3、 使用手动连接,将登录框中的取消按钮使用第2种方式的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中,在槽函数中判断ui界面上…...
中国传媒业人工智能应用发展图谱2024
易观分析:传媒产业是指以传播各类信息、知识为核心,通过多种媒介形式进行内容生产、发布和分发的综合性产业。技术的进步和应用对于传媒产业发展变革起到了核心驱动力的作用,2022年生成式AI进入应用爆发期,不仅带动了人工智能产业…...
RTX3060 FP64测试与猜想
RTX3060 FP64测试与猜想 一.小结二.查看FP64的峰值性能三.打满FP64、FP32的利用率,对比差异四.进一步证明pipe_fp64_cycles_active并不是2个fp64 core的metrics RTX3060 FP64测试与猜想 一.小结 RTX3060 compute capability为8.6,每个SM有2个FP64 core。每个cycle可输出2个fp…...
uniapp写移动端常见问题汇总
1. 手机顶部状态栏遮挡 写在需要的地方 <view class"status_bar" style"height: var(--status-bar-height); width: 100%;">2. 手机顶部状态栏字体颜色 // pages.json "statusBarStyle": "light",3. 背景覆盖全屏 page{widt…...
Linux运维排查常见故障_在tmp目录下有大量包含picture_ 的临时文件,每天晚上2 30需要对一天前的文件进行
echo“”>>/etc/security/limits.conf echo“*softnproc65535″>>/etc/security/limits.conf echo“*hardnproc65535″>>/etc/security/limits.conf echo“*softnofile65535″>>/etc/security/limits.conf echo“*hardnofile65535″>>/etc/secur…...
基于SpringBoot的智能制造云平台系统的设计与实现计算机毕设
一、选题背景与意义(300字左右) 根据工业4.0智能制造生态链中云工厂在实际生产当中的工作流程进行充分调研和整理出来的,描述最终用户在本系统中对于生产订单的处理、排产、以及生产的完整在线处理流程和业务需求的文档。 针对制造业而言&a…...
论文翻译:arxiv-2024 Benchmarking Benchmark Leakage in Large Language Models
Benchmarking Benchmark Leakage in Large Language Models https://arxiv.org/abs/2404.18824 在大型语言模型中基准测试泄露的基准测试 文章目录 在大型语言模型中基准测试泄露的基准测试摘要1 引言 图1:不同模型在基准测试的训练集上进行逐字训练相对于测试集以…...
十二、新版UI
一、UI Toolkit 这个组件是新版的UI系统 创建了一个新的UIBuild,在单独的场景中打开 未来Unity会以这个为基准。 缺点:目前没有Animator,做不了动画;没法加shader...
Path系统环境变量和CLASSPATH环境变量
Path系统环境变量 概述:Path环境变量不是java的,它隶属于windows操作系统 作用: PATH环境变量实际上就是给windows操作系统指路的。 在Path环境变量中有很多路径,路径和路径之间采用 分号(;) 隔开在DOS命令窗口中输入一条DOS命…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
