对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

存储计算数据

应用程序可能需要从数据库中存储的源数据中获取值。 计算新值可能需要大量 CPU 资源,尤其是在大型数据集或必须检查多个文档的情况下。

如果经常请求计算值,则提前将该值保存在数据库中可能会更有效。 当应用程序请求数据时,只需执行一次读操作。

如果读取明显比写入更常见,则计算模式会降低数据计算的频率。 应用程序不是在每次读取时都计算值,而是存储计算出的值并根据需要重新计算。 应用程序可以在每次写入更改计算值的源数据时重新计算该值,也可以将其作为定期作业的一部分重新计算。

注意

通过定期更新,不能保证返回的计算值的准确性。 但是,如果不要求精确性,则为提高性能而值得此方法。

在此示例中,应用程序显示电影观看器和收入信息。 用户可以查找特定的电影以及该电影赚了多少钱。

1

创建 screenings 集合:

db.screenings.insertMany( [ { theater: "Alger Cinema", location: "Lakeview, OR", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 344, revenue: 3440 }, { theater: "City Cinema", location: "New York, NY", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 1496, revenue: 22440 }, ] )
2

用户通常想知道有多少人观看了某部电影以及该电影赚了多少钱。 在当前模式中,要添加 num_viewers 和 revenue,您必须读取放映过标题为“迷失在阴影中”的电影的电影院,并对这些字段的值求和。

为避免每次请求信息时都执行该计算,您可以计算总值并将其与电影记录一起存储在 movies集合中:

db.movies.insertOne( { _id: 1, title: "Lost in the Shadows", total_viewers: 1840, total_revenue: 25880 })
3

考虑将新的筛选添加到 screenings集合中:

db.screenings.insertOne( { theater: "Overland Park Cinema", location: "Boise, ID", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 760, revenue: 7600 })

movies集合中的计算数据不再反映当前筛选数据。更新计算数据的频率取决于应用程序:

  • 在低写入环境中,计算可以与 screenings 数据的任何更新同时进行。

  • 在写入更频繁的环境中,可以按定义的时间间隔(示例每小时)完成计算。 screenings 中的源数据不受写入 movies集合的影响,因此您可以随时运行计算。

要根据放映数据更新计算数据,您可以定期运行以下聚合:

db.screenings.aggregate( [ { $group: { _id: "$movie_id", total_viewers: { $sum: "$num_viewers" }, total_revenue: { $sum: "$revenue" } } }, { $merge: { into: { db: "test", coll: "movies" }, on: "_id", whenMatched: "merge" } }] )
4

要确认 movies集合已更新,请查询该集合:

db.movies.find()

输出:

[ { _id: 1, title: 'Lost in the Shadows', total_viewers: 2600, total_revenue: 33480 }]

计算模式可减少 CPU工作负载并提高应用程序性能。 考虑应用程序重复执行相同计算并具有较高写入比率的计算模式。

获得技能徽章

免费掌握“模式设计模式和反模式”!

了解详情

给本页内容打分