【问题标题】:Can MongoDB run the same operation on many documents without querying each one?MongoDB 可以在不查询每个文档的情况下对多个文档运行相同的操作吗?
【发布时间】:2012-02-24 11:47:52
【问题描述】:

我正在寻找一种方法来更新名为“posts”的集合中的每个文档。

帖子会定期更新流行度(网站范围内的流行度)和强度(与特定用户的估计相关性),每个帖子都来自不同的来源。我需要做的是增加每个帖子的受欢迎程度和强度,以获得第三个领域,相关性。相关性用于对帖子进行排序。

class Post
  include Mongoid::Document

  field :popularity
  field :strength
  field :relevance
  ...

目前的实现如下:

1) 我将映射/归约到一个单独的集合,该集合存储帖子 ID 和计算的相关性。

2) 我从地图缩减结果中单独更新每个帖子。

这是大量的单独更新查询,将每个帖子映射到自己的结果(一对一)似乎很愚蠢,只是为了再次更新帖子。是否可以就地繁殖,或者做某种就地地图?

【问题讨论】:

  • 如果我的解决方案有效,这可能是重复的:stackoverflow.com/a/8230759/131227
  • 感谢您的链接。我犹豫是否要覆盖原始集合中的整个文档,因为帖子集合会随着用户在网站上执行操作而定期更新,而且我会担心并发性。

标签: mongodb mapreduce


【解决方案1】:

是否可以就地繁殖,或者做某种就地地图?

没有。

这里的理想情况是让 Map/Reduce 在完成后直接更新 Post。不幸的是,M/R 没有这种能力。理论上,您可以从“finalize”阶段发布更新,但这会在分片环境中崩溃。

但是,如果您所做的只是一个简单的乘法运算,那么您根本就不需要 M/R。您可以只运行一个大的for 循环,或者您可以连接save 事件以在:popularity:strength 更新时更新:relevance

MongoDB 没有触发器,因此它不能自动执行此操作。但是您使用的业务层正是放置这种逻辑的确切位置。

【讨论】:

  • 感谢您的回答。但是,帖子实际上是特定于用户的,因此可以将相同的实际内容推送到许多用户提要,但具有特定于该用户的信息(强度是用户特定的)。强度和流行度都使用原子更新进行更新,因此 before_save 不起作用。虽然我可以运行一个大的 for 循环,但这涉及到每个帖子的两个查询(一个要获取,一个要保存),而对于 M/R,我有一个 M/R,然后每个结果都有一个原子更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多