arrays - 解决 MongoDB 中的 bug #1243 的最佳方法(使用位置运算符更新数组中的所有项目)

标签 arrays mongodb

我正在编写一个数据库层,其中 1:n 记录缓存在 _children 字段中。 所以,如果你有人:

{   
  id: 1,
  name: 'Tony',
  surname: 'Mobily',
  _children: {
    addresses: [],
  }
},
{
  name: 'Chiara',
  surname: 'Mobily',
  _children: {
    addresses: [],
  }
}

然后添加一条记录到地址:

{
  id: 100
  personId: 1,
  street: 'Some street',
  country: 'Australia',
}

{
  id: 101
  personId: 1,
  street: 'Some other street',
  country: 'Australia',
}

正确的记录会在人员中自动更新:

{   
  id: 1,
  name: 'Tony',
  surname: 'Mobily',
  _children: {
    addresses: [
      {
        id: 100
        personId: 1,
        street: 'Some street',
        country: 'Australia',
      },

      {
        id: 101
        personId: 1,
        street: 'Some other street',
        country: 'Australia',
      }

    ],
  }
},

我的图层还存储所有文本字段的大写版本,并自动运行不区分大小写的搜索等。它还处理“查找”字段,自动填充它们。

当您对“地址”字段进行批量更新时,它还会对“父”字段运行更新,以便一切都同步。一切都很顺利。

除非您尝试对地址表进行大规模更新。

例如:

addresses.update( { country: 'Australia' }, { street: 'Something else' }, { multi: true } )

完成后,我还以这种方式对每个“父”表(在本例中为 people)运行查询:

people.update( { _children.country: 'Australia'}, { '_children.addresses.$.street': 'Something else' }, { multi: true } )

请注意,"new"查询会自动计算出来。

但是,由于 bug https://jira.mongodb.org/browse/SERVER-1243 ,我基本上完蛋了。

(请注意,插入始终是一个简单的操作,意味着一个简单的 $push (那里没有问题),而删除是一个需要对 _children 进行 $pull 的操作($pull 接受一个过滤器来处理数组。所以,那里也没有问题)。唯一的问题是批量更新。)

现在:

  • 由于以下几个原因,我无法加载完整文档并手动更改所有条目:(1) 性能:我需要对每个匹配的记录运行更新,可能是 100 万条; (2) 这实际上是不可能的,因为我没有办法在加载的文档上“重新运行”查询(可能涉及正则表达式等)

  • 我无法重复更新操作,直到获得零更新(它们都已更改),因为如果更改匹配,它将永远执行(如果您将 'perth' 更改为 'perth2',并匹配以 'p' 开头的任何内容。

但是,我确实需要这个功能,但我只是不知道如何做到这一点。

除了请求 MongoDB 人员解决这个问题之外,你们还有什么想法吗?这是 Mongo 数组更新的另一个弱点?

最佳答案

因此,考虑到您正在“批量更新”并且这可能是一次性操作,您可以考虑使用 db.eval()像这样:

db.eval(function() {
    db.collection.find({}).forEach(function(doc) {
        doc._children.forEach(function(item) {
            item.ucCountry = item.country.toUpperCase;
        });
        db.collection.update(
            { "_id": doc._id },
            { "$set": { "_children": doc._children } }
        );
    });
})

所以这几乎是标准循环,但这次它在服务器上运行。您甚至可以仅针对要更改的数组元素添加 $set 操作,以节省更多开销。

请注意,请阅读文档。在执行更新期间,您将锁定数据库进行写入,并阻止所有其他 JavaScript 操作,例如“mapReduce”。但这是最快的方法。

关于arrays - 解决 MongoDB 中的 bug #1243 的最佳方法(使用位置运算符更新数组中的所有项目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22420712/

相关文章:

python - 如何关闭 mongodb python 连接?

MongoDB - 计算包含数组元素的数组中的值的$sum

javascript - 将查询从 react 前端传递到羽毛服务是好的做法吗?

php - 通知 : Array to string conversion with date

arrays - char *name[10] 和 char (*name)[10] 有什么区别?

arrays - 如何使用吗啡过滤mongo文档中的嵌入数组

javascript - 如何在 Node JS 回调中获取 MongoDB collection.aggregate() 的结果?

ruby-on-rails - 将逗号分隔的字符串转换为 Rails 中 postgres 的数组会产生意外的结果

c++ - 将 double 转换并连接到字节数组

python - 如何将多个csv文件导入MongoDB?