首页 > 解决方案 > Mongodb根据少量条件为大量文档将字段从一个集合添加到另一个集合

问题描述

我遇到了以下情况,我需要非常频繁地更新大量集合。

我有一个像下面这样的集合

coll1
{
  "identification_id" : String,
  "name" : String,
  "mobile_number" : Number,
  "location" : String,
  "user_properties" : [Mixed types],
  "profile_url" : String
}

coll2
{
  "identification_id": String,
  "user_id" : String,
  "name" : String,
  "mobile_number" : Number,
  "location" : String,
  "user_properties" : String,
  "profile_url": String,
  "qualified_user" : String,
  "user_interest_stage" :Number,
  "source" : String,
  "fb_id" : String,
  "comments":String
}

updated coll1
{
  "identification_id": String,
  "name" : String,
  "mobile_number" : Number,
  "location" : String,
  "user_properties" : String,
  "profile_url": String,
  "qualified_user" : String,
  "user_interest_stage" :Number,
  "source" : String,
  "fb_id" : String,
  "comments":String
}

正如您所看到的 coll1 和 coll2,下面将插入文档场景

  1. 如果来自 coll1 的用户在某些场景下对产品表现出兴趣是合格的,我将在 coll2 中创建一条记录。
  2. 手动我可以从 coll2 中的 API 信息创建新记录
  3. coll2 中 coll1 的标识是 user_id
  4. coll1 中的一条记录可能在 coll2 中有多个记录

现在由于某些原因,我们将这些集合合并为一个集合,即 coll1。我们决定根据键 'qualified_user' 更新合格的访问者,并更新 coll1 中的相应用户字段。

我编写了一个脚本,使用 Node JS 和 mongoose,它将从 coll1 获取文档并验证 coll2 中的qualified_user 并根据以下场景进行更新。

  1. 如果没有合格用户,则使用不合格用户的默认值更新文档
  2. 如果有一个合格用户,则从 coll2 复制资格文件并在 coll1 中更新
  3. 如果有多个合格用户复制第一个文档并在 coll1 中更新。对于 coll2 中的其余文档,在 coll1 中创建一个新文档
  4. coll1 处理完所有文档后,处理 coll2 文档,这些文档通过 API 限定,并在 coll1 中创建一个新文档。

当我运行此脚本时,出现以下错误。

<--- JS stacktrace --->

==== JS stack trace =========================================

coll1 中的文档数为 1L。由于处理了大量的收藏品,我遇到了这种情况。所以我使用了跳过和限制来处理所有文件,但处理所有文件需要 1 小时。

有没有更好的方法来处理大量集合的这些类型的数据库更新?

标签: javascriptmongodbmongoosenodejs-server

解决方案


您试图一次保存太多文档,这会使您的内存不足。

您有两个简单的选择:

  1. 使用 Mongo 的游标来迭代结果,而不是一次获取所有结果。
  2. 运行脚本时使用--max-old-space-size标志,您可以手动设置脚本可以访问的内存量,如下所示:node --max-old-space-size=4096 script.js

话虽如此,这两个都不是最佳的,假设你的规模将不断增加,最终两者都将不起作用。我个人建议重新考虑数据结构。Mongo 作为一种非结构化语言并不能很好地处理数据重复。这意味着您“想要”将所有数据保存在一个集合中,然后在特定条件下更新特定字段。


推荐阅读