当前位置: 首页 > news >正文

【MongoDB】多种聚合操作详解,案例分析

1. 算术表达式操作符 ($abs)

// 插入数据
db.temperatureChange.insertMany([{ _id: 1, startTemp: 50, endTemp: 80 },{ _id: 2, startTemp: 40, endTemp: 40 },{ _id: 3, startTemp: 90, endTemp: 70 },{ _id: 4, startTemp: 60, endTemp: 70 }
]);// 计算温度差的绝对值
db.temperatureChange.aggregate([{$project: {delta: { $abs: { $subtract: ["$startTemp", "$endTemp"] } }}}
]);

2. 数组表达式操作符 ($arrayElemAt)

// 插入数据
db.users.insertMany([{ _id: 1, name: "dave123", favorites: ["chocolate", "cake", "butter", "apples"] },{ _id: 2, name: "li", favorites: ["apples", "pudding", "pie"] },{ _id: 3, name: "ahn", favorites: ["pears", "pecans", "chocolate", "cherries"] },{ _id: 4, name: "ty", favorites: ["ice cream"] }
]);// 获取数组首尾元素
db.users.aggregate([{$project: {name: 1,first: { $arrayElemAt: ["$favorites", 0] },last: { $arrayElemAt: ["$favorites", -1] }}}
]);

3. 按位操作符 ($bitAnd)

// 插入数据
db.switches.insertMany([{ _id: 0, a: NumberInt(0), b: NumberInt(127) },{ _id: 1, a: NumberInt(2), b: NumberInt(3) },{ _id: 2, a: NumberInt(3), b: NumberInt(5) }
]);// 按位与运算
db.switches.aggregate([{$project: {result: { $bitAnd: ["$a", "$b"] }}}
]);

4. 布尔表达式操作符 ($and)

// 插入数据
db.inventory.insertMany([{ _id: 1, item: "abc1", qty: 300 },{ _id: 2, item: "abc2", qty: 200 },{ _id: 3, item: "xyz1", qty: 250 },{ _id: 4, item: "wxz1", qty: 300 },{ _id: 5, item: "wxz2", qty: 180 }
]);// 检查数量范围
db.inventory.aggregate([{$project: {item: 1,qty: 1,result: { $and: [{ $gt: ["$qty", 100] },{ $lt: ["$qty", 250] }]}}}
]);

5. 条件表达式操作符 ($cond)

// 插入数据
db.inventory.insertMany([{ _id: 1, item: "abc1", qty: 300 },{ _id: 2, item: "abc2", qty: 200 },{ _id: 3, item: "xyz1", qty: 260 }
]);// 条件折扣计算
db.inventory.aggregate([{$project: {item: 1,discount: {$cond: {if: { $gte: ["$qty", 260] },then: 30,else: 20}}}}
]);

6. 日期操作符 ($dateAdd)

// 插入数据
db.shipping.insertMany([{ custId: 456, purchaseDate: ISODate("2020-12-31") },{ custId: 457, purchaseDate: ISODate("2021-02-28") },{ custId: 458, purchaseDate: ISODate("2021-02-26") }
]);// 计算预计交付日期(+3天)
db.shipping.aggregate([{$project: {expectedDeliveryDate: {$dateAdd: {startDate: "$purchaseDate",unit: "day",amount: 3}}}}
]);

7. 字符串操作符 ($concat)

// 插入数据
db.inventory.insertMany([{ _id: 1, item: "ABC1", description: "product 1" },{ _id: 2, item: "ABC2", description: "product 2" },{ _id: 3, item: "XYZ1", description: null }
]);// 拼接字符串
db.inventory.aggregate([{$project: {itemDescription: { $concat: ["$item", " - ", "$description"] }}}
]);

8. 累加器操作符 ($addToSet)

// 插入数据
db.sales.insertMany([{ _id: 1, item: "abc", date: ISODate("2014-01-01T08:00:00Z") },{ _id: 2, item: "jkl", date: ISODate("2014-02-03T09:00:00Z") },{ _id: 3, item: "xyz", date: ISODate("2014-02-03T09:05:00Z") },{ _id: 4, item: "abc", date: ISODate("2014-02-15T08:00:00Z") }
]);// 按日期分组统计唯一商品
db.sales.aggregate([{$group: {_id: {day: { $dayOfYear: "$date" },year: { $year: "$date" }},itemsSold: { $addToSet: "$item" }}}
]);

9. 变量操作符 ($let)

// 插入数据
db.sales.insertMany([{ _id: 1, price: 10, tax: 0.50, applyDiscount: true },{ _id: 2, price: 10, tax: 0.25, applyDiscount: false }
]);// 使用变量计算最终价格
db.sales.aggregate([{$project: {finalTotal: {$let: {vars: {total: { $add: ["$price", "$tax"] },discounted: { $cond: { if: "$applyDiscount", then: 0.9, else: 1 } }},in: { $multiply: ["$$total", "$$discounted"] }}}}}
]);

关键说明:

  1. 字段修正:所有 -id 已修正为 _id
  2. 数据类型
    • 日期使用 ISODate()
    • 整数使用 NumberInt()
  3. 操作符注意
    • $arrayElemAt:索引从0开始,-1表示最后一个元素
    • $cond:三元运算符(条件 ? 值1 : 值2)
    • $let:先定义变量再使用($$变量名
  4. 执行顺序
    1. 创建集合 → 2. 插入数据 → 3. 执行聚合管道
    
  5. 版本要求
    • 按位操作符需要 MongoDB 6.3+
    • 窗口函数需要 MongoDB 5.0+

建议逐段复制执行,每次执行前确保集合存在且数据格式正确。遇到语法错误时,检查括号闭合和逗号使用。


$mergeObjects 与集合表达式

场景说明

我们有两个集合:orders(订单)和items(商品)。我们需要将这两个集合的数据按照商品编号(item)进行关联,得到包含订单信息和商品库存信息的完整文档。

准备数据
// 创建orders集合并插入数据
db.orders.insertMany([{ "_id": 1, "item": "abc", "price": 12, "ordered": 2 },{ "_id": 2, "item": "jkl", "price": 20, "ordered": 1 }
])
// 创建items集合并插入数据
db.items.insertMany([{ "_id": 1, "item": "abc", description: "product 1", "instock": 120 },{ "_id": 2, "item": "def", description: "product 2", "instock": 80 },{ "_id": 3, "item": "jkl", description: "product 3", "instock": 60 }
])
执行$lookup聚合操作

我们分三次执行,以便更好理解命令参数

  • 左连接操作(orders)
db.orders.aggregate([{$lookup: {from: "items",localField: "item", // ordersforeignField: "item",	// itemsas: "fromItems"}}
])
  • 可以看到orders的左连接合并结果是以我们提供的 as: "fromItems"为字段的数组
    在这里插入图片描述
  • 我们需要把数组提出来,合并到根文档上,让两表各自所需的字段合在一起
db.orders.aggregate([{$lookup: {from: "items",localField: "item",foreignField: "item",as: "fromItems"}},{$replaceRoot: {newRoot: {$mergeObjects: [{ $arrayElemAt: ["$fromItems", 0]},"$$ROOT"]}}}
])

在这里插入图片描述

  • 接下来就是隐藏fromItems数组
db.orders.aggregate([{$lookup: {from: "items",localField: "item",foreignField: "item",as: "fromItems"}},{$replaceRoot: {newRoot: {$mergeObjects: [{ $arrayElemAt: ["$fromItems", 0]},"$$ROOT"]}}},{$project: { fromItems: 0}}
])

在这里插入图片描述


http://www.dtcms.com/a/337823.html

相关文章:

  • Java文件操作/IO
  • RabbitMQ高级特性——TTL、死信队列、延迟队列、事务、消息分发
  • 【展厅多媒体】互动地砖屏怎么提升展厅互动感的?
  • python基于机器学习进行数据处理与预测(火灾的三因素回归问题)
  • 探索机器学习:从核心概念到实战应用
  • 精通sqlmap tamper:WAF绕过实战技巧剖析
  • 磁流变液迟滞性能的机器学习软件设计
  • MySQL实战优化高手教程 – 从架构原理到生产调优
  • 突破成长瓶颈:产品运营能力体系化提升技巧
  • 大数据毕业设计选题推荐:基于Hadoop+Spark的城镇居民食品消费分析系统源码
  • 28、企业安防管理(Security)体系构建:从生产安全到日常安保的全方位防护
  • 【秋招笔试】2025.08.16科大讯飞秋招机考真题
  • 从虚拟到现实:数字孪生赋能智能制造
  • 跨设备文件共享优化:cpolar 提升 PicoShare 访问速度方案
  • Nextcloud 私有云部署:cpolar 内网穿透服务实现安全远程文件访问
  • 知识点 | 麒麟OS环境中curl -4回显真实IP的原因
  • Nextcloud容器化部署革新:Docker+Cpolar构建高效私有云远程访问新架构
  • Harmonyos之字体设置功能
  • 什么是Hystrix?实现原理是什么?
  • Hadoop - 1:Hadoop 技术解析;Hadoop是什么;Hadoop优势;Hadoop组成;HDFS、YARN、MapReduce 三者关系
  • docker——docker执行roslaunch显示错误
  • listagg 多了空格 Oracle数据库
  • 【嵌入式人工智能产品开发实战】(二十四)—— 政安晨:解释一下小智AI项目中析构函数的应用
  • McCabe 环形复杂度
  • Owen大规模文本嵌入生成
  • PMP-项目管理-十大知识领域:风险管理-识别、评估、应对项目风险
  • nsfp-
  • 《Image Classification with Classic and Deep Learning Techniques》复现
  • 地图导航怎么测?
  • 深入浅出决策树