mongodb - 如何根据日期范围 mongoDB 选择所有数据?
问题描述
我有如下记录列表
[
{
"product": "p1",
"salesdate": "2020-02-01",
"amount": 100
},
{
"product": "p2",
"salesdate": "2020-02-04",
"amount": 200
},
]
2 月 2 日和 2 月 3 日我没有数据。但我需要在我的结果中添加它。我的预期结果是
[
{
"amount": 100,
"salesdate": "2020-02-01"
},
{
"amount": 0,
"salesdate": "2020-02-02"
},
{
"amount": 0,
"salesdate": "2020-02-03"
}
{
"amount": 200,
"salesdate": "2020-02-04"
}
]
我可以使用 mongoDB 实现这一点吗?
解决方案
你可以使用$reduce
它。每当必须使用数据/时间值时,我推荐moment.js库。您不必使用它,但它使您的生活更轻松。
db.collection.aggregate([
// Put all data into one document
{ $group: { _id: null, data: { $push: "$$ROOT" } } },
// Add missing days
{
$addFields: {
data: {
$reduce: {
// Define the range of date
input: { $range: [0, moment().get('day')] },
initialValue: [],
in: {
$let: {
vars: {
ts: {
$add: [moment().startOf('month').toDate(), { $multiply: ["$$this", 1000 * 60 * 60 * 24] }]
}
},
in: {
$concatArrays: [
"$$value",
[{
$ifNull: [
{ $first: { $filter: { input: "$data", cond: { $eq: ["$$this.salesdate", "$$ts"] } } } },
// Default value for missing days
{ salesdate: "$$ts", amount: 0 }
]
}]
]
}
}
}
}
}
}
},
{ $unwind: "$data" },
{ $replaceRoot: { newRoot: "$data" } }
// If requried add further $group stages
])
请注意,此代码返回从当前月份的第一天到当前日期的值(不是示例数据中的 2020 年)。您可以调整范围 - 您的要求从问题中不清楚。
推荐阅读
- vue.js - 在 vue 中从子级向父级添加组件
- grafana - 如何将主页仪表板放在 Grafana 仪表板列表的顶部?
- sql-server-2008 - FireDAC、阵列 DML、SQL Server 和 IDENTITY_INSERT
- assembly - sys_write 输出额外字符
- javascript - 我想:只通过一个扬声器播放 .mp3
- bootstrap-4 - Groupby:多选单选按钮
- apache-spark - 为什么我的 IDE 对 Spark SQL 2.4.4 依赖项显示“未知工件。未解析或索引”?
- python - 我想将此代码转换为完整的句子
- python - PyQt5 是否可用于 Python 3.8?我无法安装 pyqt5-tools
- javascript - 如何使用 React 解密 Laravel cookie