Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

存储计算数据

在此页面上

  • 关于此任务
  • 步骤
  • 结果
  • 了解详情

应用程序可能需要从数据库中存储的源数据中获取值。计算新值可能需要大量 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_viewersrevenue ,您必须读取放映过标题为“迷失在阴影中”的电影的电影院,并对这些字段的值求和。

为避免每次请求信息时都执行该计算,您可以计算总值并将其与电影记录一起存储在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工作负载并提高应用程序性能。考虑应用程序重复执行相同计算并具有较高写入比率的计算模式。

  • 使用近似模式

  • 分组数据

  • 数据一致性

后退

计算值