定时触发器
定时触发器支持您按照定义的定期计划执行服务器端逻辑。您可以使用定时触发器来执行定期发生的工作,例如每分钟更新一次文档、每晚生成一次报告或每周自动发送一次电子邮件简讯。
创建定时触发器
要在 Atlas App Services 用户界面中创建定时触发器:
单击左侧导航菜单中 Build 下的 Triggers。
单击 Create a Trigger 打开触发器配置页面。
为 Trigger Type 选择 Scheduled。
要使用 App Services CLI 创建定时触发器,请执行以下操作:
将定时触发器配置文件添加到本地应用程序目录的
triggers
子目录中。注意
您无法使用 App Services CLI 创建按照 Basic 计划运行的触发器。所有导入的定时触发器配置必须指定 CRON 表达式。
定时触发器配置文件采用以下格式:
/triggers/<triggers name>.json{ "type": "SCHEDULED", "name": "<Trigger Name>", "function_name": "<Trigger Function Name>", "config": { "schedule": "<CRON expression>" }, "disabled": <boolean> } 部署 trigger:
appservices push
配置
定时触发器具有以下配置选项:
字段 | 说明 |
---|---|
Trigger Type type: <string> | 选择 Scheduled 。 |
Schedule Type config.schedule: <string> | 必填。您可以选择 Basic(基本)或 Advanced(高级)。Basic 计划根据您设置的时间间隔定期执行触发器,例如“每五分钟”或“每周一”。 高级计划根据您定义的自定义 CRON 表达式运行 Trigger。 |
Skip Events on Re-Enable skip_catchup_event: <boolean> | 默认禁用。如果启用,则不会处理在禁用此触发器时发生的任何变更事件。 |
Event Type function_name: <string> | 在 Event Type(函数)部分,您可以选择触发器触发时要执行的操作。您可以选择运行函数或使用 AWS EventBridge。 注意定时触发器不会向其关联的函数传递任何参数。 |
Trigger Name name: <string> | 触发器名称。 |
CRON 表达式
CRON 表达式是用户定义的字符串,它使用标准的 cron 作业语法来定义定时触发器的执行时间。应用程序服务根据 UTC 时间执行触发器 CRON 表达式。只要 CRON 表达式中的所有字段与当前日期和时间匹配,应用程序服务就会触发与表达式关联的触发器。
表达式事务语法
format
CRON 表达式是由五个空格分隔字段组成的字符串。每个字段都定义了执行相关触发器的计划的粒度部分:
* * * * * │ │ │ │ └── weekday...........[0 (SUN) - 6 (SAT)] │ │ │ └──── month.............[1 (JAN) - 12 (DEC)] │ │ └────── dayOfMonth........[1 - 31] │ └──────── hour..............[0 - 23] └────────── minute............[0 - 59]
字段 | Valid Values | 说明 |
---|---|---|
minute | [0 - 59] | 表示一小时内的一分钟或多分钟。 例子如果 CRON 表达式的 |
hour | [0 - 23] | 采用 24 小时制,表示一天中的一个或多个小时。 例子如果 CRON 表达式 |
dayOfMonth | [1 - 31] | 表示一个月内的一天或多天。 例子如果 CRON 表达式的 |
month | 1 (JAN) 7 (JUL) 2 (FEB) 8 (AUG) 3 (MAR) 9 (SEP) 4 (APR) 10 (OCT) 5 (MAY) 11 (NOV) 6 (JUN) 12 (DEC) | 表示一年内的一个月或多个月。 月份可以用数字(例如 例子如果 CRON 表达式 |
weekday | 0 (SUN) 1 (MON) 2 (TUE) 3 (WED) 4 (THU) 5 (FRI) 6 (SAT) | 表示一周内的一天或多天。 工作日可以用数字表示(例如 例子如果 CRON 表达式 |
字段值
CRON 表达式中的每个字段都可以包含特定值或计算结果为一组值的表达式。下表描述了有效的字段值和表达式:
表达式类型 | 说明 | |
---|---|---|
All Values (*) | 匹配所有可能的字段值。 可用于所有表达式字段。 例子以下 CRON 表达式安排触发器每天每分钟执行一次:
| |
Specific Value (<Value>) | 匹配特定字段值。对于 可用于所有表达式字段。 例子以下 CRON 表达式安排触发器在 UTC 时间每天上午 11:00 执行一次:
| |
List of Values (<Expression1>,<Expression2>,...) | 匹配包含两个或更多字段表达式或特定值的列表。 可用于所有表达式字段。 例子以下 CRON 表达式安排触发器在一月、三月和七月每天上午 11:00 UTC 执行一次:
| |
Range of Values (<Start Value>-<End Value>) | 匹配介于两个特定字段值之间(包含这两个特定值)的连续范围的字段值。 可用于所有表达式字段。 例子以下 CRON 表达式安排触发器在 UTC 时间 1 月 1 日至 4 月底的每天上午 11:00 执行一次:
| |
Modular Time Step (<Field Expression>/<Step Value>) | 匹配步长值整除字段值且无余数的任何时间(即 在 例子以下 CRON 表达式安排触发器在每小时的第 0、25 和 50 分钟执行:
|
例子
在线商店希望每天生成前一天所有销售额的报告。它们将 store.orders
集合中的所有订单记录为类似于以下内容的文档:
{ _id: ObjectId("59cf1860a95168b8f685e378"), customerId: ObjectId("59cf17e1a95168b8f685e377"), orderDate: ISODate("2018-06-26T16:20:42.313Z"), shipDate: ISODate("2018-06-27T08:20:23.311Z"), orderContents: [ { qty: 1, name: "Earl Grey Tea Bags - 100ct", price: Decimal128("10.99") } ], shippingLocation: [ { location: "Memphis", time: ISODate("2018-06-27T18:22:33.243Z") }, ] }
为了生成每日报告,存储创建了一个定时触发器,每天在 7:00 AM UTC
时触发。触发器触发后,会调用其链接的 Atlas Function generateDailyReport
,该函数对 store.orders
集合运行聚合查询,生成报告。然后,此函数将聚合结果存储在 store.reports
集合中。
{ "type": "SCHEDULED", "name": "reportDailyOrders", "function_name": "generateDailyReport", "config": { "schedule": "0 7 * * *" }, "disabled": false }
exports = function() { // Instantiate MongoDB collection handles const mongodb = context.services.get("mongodb-atlas"); const orders = mongodb.db("store").collection("orders"); const reports = mongodb.db("store").collection("reports"); // Generate the daily report return orders.aggregate([ // Only report on orders placed since yesterday morning { $match: { orderDate: { $gte: makeYesterdayMorningDate(), $lt: makeThisMorningDate() } } }, // Add a boolean field that indicates if the order has already shipped { $addFields: { orderHasShipped: { $cond: { if: "$shipDate", // if shipDate field exists then: 1, else: 0 } } } }, // Unwind individual items within each order { $unwind: { path: "$orderContents" } }, // Calculate summary metrics for yesterday's orders { $group: { _id: "$orderDate", orderIds: { $addToSet: "$_id" }, numSKUsOrdered: { $sum: 1 }, numItemsOrdered: { $sum: "$orderContents.qty" }, totalSales: { $sum: "$orderContents.price" }, averageOrderSales: { $avg: "$orderContents.price" }, numItemsShipped: { $sum: "$orderHasShipped" }, } }, // Add the total number of orders placed { $addFields: { numOrders: { $size: "$orderIds" } } } ]).next() .then(dailyReport => { reports.insertOne(dailyReport); }) .catch(err => console.error("Failed to generate report:", err)); }; function makeThisMorningDate() { return setTimeToMorning(new Date()); } function makeYesterdayMorningDate() { const thisMorning = makeThisMorningDate(); const yesterdayMorning = new Date(thisMorning); yesterdayMorning.setDate(thisMorning.getDate() - 1); return yesterdayMorning; } function setTimeToMorning(date) { date.setHours(7); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); return date; }
性能优化
使用带有 $match 表达式的查询 API 来减少函数查看的文档数量。这有助于提高函数性能并且不会达到函数内存限制。
有关使用 $match 表达式的定时触发器,请参阅示例部分。
其他示例
有关集成到 App Services 应用程序中的触发器的其他示例,请查看 Github 上的触发器示例。