存储计算数据
应用程序可能需要从数据库中存储的源数据中获取值。 计算新值可能需要大量 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
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" } } ] )
结果
计算模式可减少 CPU工作负载并提高应用程序性能。 考虑应用程序重复执行相同计算并具有较高写入比率的计算模式。