MongoDB 聚合查询以过滤 7 天前创建的文档
MongoDB aggregate query to filter documents created 7 days ago
我想过滤数据集以提取 7 天前创建的文档 OR 一个月前 OR 在任何日期创建的文档.
根据文档中的 createdAt 字段过滤文档。
数据集:-
[
{
"_id": ObjectId("6257047cffd61ab62864c1ae"),
"type": "A",
"source": "B",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-17T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ad"),
"type": "B",
"source": "A",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-23T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-23T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ce"),
"type": "A",
"source": "C",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-17T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1cb"),
"type": "A",
"source": "B",
"user": ObjectId("622b56250b0af6b049c387d6"),
"createdAt": ISODate("2022-04-24T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-24T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1cb"),
"type": "A",
"source": "B",
"user": ObjectId("622b56250b0af6b049c387d6"),
"createdAt": ISODate("2022-03-24T07:55:00.368Z"),
"updatedAt": ISODate("2022-03-24T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ce"),
"type": "A",
"source": "C",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-03-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-03-17T07:55:00.368Z"),
},
]
MongoDB聚合查询:-
db.collection.aggregate([
{
$addFields: {
paramType: "All",
paramSource: "All",
paramCreatedAt:"All",
}
},
{
$match: {
$and: [
{
user: ObjectId("622b55ff0b0af6b049c387d3")
},
{
$or: [
{
paramType: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramType",
"$type"
],
}
}
]
},
{
$or: [
{
paramSource: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramSource",
"$source"
]
}
}
]
}
]
}
},
{
$setWindowFields: {
output: {
totalCount: {
$count: {}
}
}
}
},
{
$sort: {
createdAt: -1
}
},
{
$skip: 0
},
{
$limit: 6
},
{
"$project": {
"paramSource": false,
"paramType": false,
}
}
])
如何过滤以获取最近 7 天或 30 天或任何日期内创建的文档。
paramCreatedAt 将采用以下值之一 [All dates, 7 days ago, a month ago]
例子:-
- 如果应用
All dates
过滤器,则显示所有记录。
- 如果应用
7 days
过滤器,显示从当前日期(可以是任何一天,不一定是星期日)到 7 天前创建的记录。
- 如果应用
30 days
过滤器,则显示最近 30 天内创建的记录
你的骨架很整齐,其实很接近。对于日期过滤,只需使用 $dateDiff
到 return 日期差异(以天为单位),然后使用 $switch
[=14 将其与您选择的天数间隔(即 7 天或 30 天)进行比较=]
db.collection.aggregate([
{
$addFields: {
paramType: "All",
paramSource: "All",
paramCreatedAt: "All dates"// [All dates, 7 days ago, a month ago]
}
},
{
$match: {
$and: [
{
user: ObjectId("622b55ff0b0af6b049c387d3")
},
{
$or: [
{
paramType: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramType",
"$type"
],
}
}
]
},
{
$or: [
{
paramSource: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramSource",
"$source"
]
}
}
]
},
{
$or: [
{
paramCreatedAt: {
$eq: "All dates"
}
},
{
$expr: {
$and: [
{
"$in": [
"$paramCreatedAt",
[
"7 days ago",
"a month ago"
]
]
},
{
$lte: [
{
"$dateDiff": {
"startDate": "$createdAt",
"endDate": "$$NOW",
"unit": "day"
}
},
{
"$switch": {
"branches": [
{
"case": {
$eq: [
"$paramCreatedAt",
"7 days ago"
]
},
"then": 7
},
{
"case": {
$eq: [
"$paramCreatedAt",
"a month ago"
]
},
"then": 30
}
]
}
}
]
}
]
}
}
]
}
]
}
},
{
$setWindowFields: {
output: {
totalCount: {
$count: {}
}
}
}
},
{
$sort: {
createdAt: -1
}
},
{
$skip: 0
},
{
$limit: 6
},
{
"$project": {
"paramSource": false,
"paramType": false,
}
}
])
这里是Mongo playground供大家参考。
这是使用 $facet
的替代方法。 $facet
非常方便,因为它允许您“并行匹配和分组”并创建 重叠 文档桶。在聚合字段上具有 $group
和 $cond
的单个管道适用于不需要重叠且需要优先顺序的“if/then/elif/elif/else”结构。
db.foo.aggregate([
// Initial filter(s):
{$match: {user: ObjectId("622b55ff0b0af6b049c387d3")}},
// Create a single version of "now" from the perspective of the
// CLIENT to use in queries to follow.
// To create such a target date from the perspective of the SERVER,
// use {$addFields: {DD: '$$NOW'}}
// Probably overkill but OK.
{$addFields: {DD: new ISODate()}},
{$facet: {
"all": [ ], // not exciting! :-)
"exactly_7_days_ago": [
{$match: {$expr:
{$eq: [7, {$floor: {$divide:[{$subtract:['$DD', '$createdAt'] }, 1000 * 60 * 60 * 24]}} ]}
}}
],
"everything_from_last_month": [
{$match: {$expr:
{$eq: [1, {$subtract:[{$month: '$DD'}, {$month: '$createdAt'} ]} ]}
}}
],
"only_one_day_from_last_month": [
{$match: {$expr:
{$and: [
{$eq: [1, {$subtract:[{$month: '$DD'}, {$month: '$createdAt'}]} ]},
{$eq: [0, {$subtract:[{$dayOfMonth: '$DD'}, {$dayOfMonth: '$createdAt'} ]} ]}
]}
}}
],
}}
]);
我想过滤数据集以提取 7 天前创建的文档 OR 一个月前 OR 在任何日期创建的文档.
根据文档中的 createdAt 字段过滤文档。
数据集:-
[
{
"_id": ObjectId("6257047cffd61ab62864c1ae"),
"type": "A",
"source": "B",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-17T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ad"),
"type": "B",
"source": "A",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-23T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-23T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ce"),
"type": "A",
"source": "C",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-04-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-17T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1cb"),
"type": "A",
"source": "B",
"user": ObjectId("622b56250b0af6b049c387d6"),
"createdAt": ISODate("2022-04-24T07:55:00.368Z"),
"updatedAt": ISODate("2022-04-24T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1cb"),
"type": "A",
"source": "B",
"user": ObjectId("622b56250b0af6b049c387d6"),
"createdAt": ISODate("2022-03-24T07:55:00.368Z"),
"updatedAt": ISODate("2022-03-24T07:55:00.368Z"),
},
{
"_id": ObjectId("6257047cffd61ab62864c1ce"),
"type": "A",
"source": "C",
"user": ObjectId("622b55ff0b0af6b049c387d3"),
"createdAt": ISODate("2022-03-17T07:55:00.368Z"),
"updatedAt": ISODate("2022-03-17T07:55:00.368Z"),
},
]
MongoDB聚合查询:-
db.collection.aggregate([
{
$addFields: {
paramType: "All",
paramSource: "All",
paramCreatedAt:"All",
}
},
{
$match: {
$and: [
{
user: ObjectId("622b55ff0b0af6b049c387d3")
},
{
$or: [
{
paramType: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramType",
"$type"
],
}
}
]
},
{
$or: [
{
paramSource: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramSource",
"$source"
]
}
}
]
}
]
}
},
{
$setWindowFields: {
output: {
totalCount: {
$count: {}
}
}
}
},
{
$sort: {
createdAt: -1
}
},
{
$skip: 0
},
{
$limit: 6
},
{
"$project": {
"paramSource": false,
"paramType": false,
}
}
])
如何过滤以获取最近 7 天或 30 天或任何日期内创建的文档。
paramCreatedAt 将采用以下值之一 [All dates, 7 days ago, a month ago]
例子:-
- 如果应用
All dates
过滤器,则显示所有记录。 - 如果应用
7 days
过滤器,显示从当前日期(可以是任何一天,不一定是星期日)到 7 天前创建的记录。 - 如果应用
30 days
过滤器,则显示最近 30 天内创建的记录
你的骨架很整齐,其实很接近。对于日期过滤,只需使用 $dateDiff
到 return 日期差异(以天为单位),然后使用 $switch
[=14 将其与您选择的天数间隔(即 7 天或 30 天)进行比较=]
db.collection.aggregate([
{
$addFields: {
paramType: "All",
paramSource: "All",
paramCreatedAt: "All dates"// [All dates, 7 days ago, a month ago]
}
},
{
$match: {
$and: [
{
user: ObjectId("622b55ff0b0af6b049c387d3")
},
{
$or: [
{
paramType: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramType",
"$type"
],
}
}
]
},
{
$or: [
{
paramSource: {
$eq: "All"
}
},
{
$expr: {
$eq: [
"$paramSource",
"$source"
]
}
}
]
},
{
$or: [
{
paramCreatedAt: {
$eq: "All dates"
}
},
{
$expr: {
$and: [
{
"$in": [
"$paramCreatedAt",
[
"7 days ago",
"a month ago"
]
]
},
{
$lte: [
{
"$dateDiff": {
"startDate": "$createdAt",
"endDate": "$$NOW",
"unit": "day"
}
},
{
"$switch": {
"branches": [
{
"case": {
$eq: [
"$paramCreatedAt",
"7 days ago"
]
},
"then": 7
},
{
"case": {
$eq: [
"$paramCreatedAt",
"a month ago"
]
},
"then": 30
}
]
}
}
]
}
]
}
}
]
}
]
}
},
{
$setWindowFields: {
output: {
totalCount: {
$count: {}
}
}
}
},
{
$sort: {
createdAt: -1
}
},
{
$skip: 0
},
{
$limit: 6
},
{
"$project": {
"paramSource": false,
"paramType": false,
}
}
])
这里是Mongo playground供大家参考。
这是使用 $facet
的替代方法。 $facet
非常方便,因为它允许您“并行匹配和分组”并创建 重叠 文档桶。在聚合字段上具有 $group
和 $cond
的单个管道适用于不需要重叠且需要优先顺序的“if/then/elif/elif/else”结构。
db.foo.aggregate([
// Initial filter(s):
{$match: {user: ObjectId("622b55ff0b0af6b049c387d3")}},
// Create a single version of "now" from the perspective of the
// CLIENT to use in queries to follow.
// To create such a target date from the perspective of the SERVER,
// use {$addFields: {DD: '$$NOW'}}
// Probably overkill but OK.
{$addFields: {DD: new ISODate()}},
{$facet: {
"all": [ ], // not exciting! :-)
"exactly_7_days_ago": [
{$match: {$expr:
{$eq: [7, {$floor: {$divide:[{$subtract:['$DD', '$createdAt'] }, 1000 * 60 * 60 * 24]}} ]}
}}
],
"everything_from_last_month": [
{$match: {$expr:
{$eq: [1, {$subtract:[{$month: '$DD'}, {$month: '$createdAt'} ]} ]}
}}
],
"only_one_day_from_last_month": [
{$match: {$expr:
{$and: [
{$eq: [1, {$subtract:[{$month: '$DD'}, {$month: '$createdAt'}]} ]},
{$eq: [0, {$subtract:[{$dayOfMonth: '$DD'}, {$dayOfMonth: '$createdAt'} ]} ]}
]}
}}
],
}}
]);