【问题标题】:"Field name duplication not allowed with modifiers" on update更新时“不允许使用修饰符重复字段名称”
【发布时间】:2011-01-03 13:06:45
【问题描述】:

我在尝试更新 Mongo 中的字段时收到“不允许使用修饰符重复字段名称”错误。一个例子:

> db.test.insert({test: "test1", array: [0]});
> var testFetch = db.test.findOne({test: "test1"});
> db.test.update(testFetch, 
                 {$push: {array: 1}, //push element to end of key "array"
                  $pop:  {array: -1} //pop element from the start of key "array"
                 });
  Field name duplication not allowed with modifiers

有没有办法执行这个原子操作?我不想为此做两个单独的更新。

【问题讨论】:

标签: mongodb


【解决方案1】:

Mongo 的票务系统上有一个未解决的问题:http://jira.mongodb.org/browse/SERVER-1050

看起来它已安排在今年。你的场景绝对是一个明智的场景,但它也与一堆边缘情况有关。如果你 $push$pop 在一个空数组上怎么办?有什么期望?如果你$push$pull你想要什么?

我不想为此做两个单独的更新。

我知道这样做确实有“代码异味”,但它是否完全阻碍了使用此解决方案? “双重更新”会彻底破坏服务器性能吗?

【讨论】:

  • 我遇到了同样的错误。不过,考虑到 MongoDB 的原子性,我认为这里的“双重更新”问题是一个严重的问题。如果您有多个应用程序可能会更新数组的同一部分,那么您真的不想在一个操作中 $pull 然后在另一个操作中 $push ...在这两个操作之间,其他一些进程可能已经更改了相同的数组元素,这可能导致不良/意外行为。
  • 我同意,这里肯定存在数据问题。但这真的取决于你为什么要这样做$push / $pull。在某些情况下,您只是在构建一个队列数组,而订单实际上可能并没有那么大。根据 JIRA 票证,这显然是一个受欢迎的问题(53 票),但它也被标记为次要和未计划。按照目前的发展速度,这可能要好几个月才能见分晓。也就是说,要使其正常工作,您仍然需要消除所有边缘情况。
  • 我实际上在尝试解决并发问题时找到了解决方案。最新版本的 MongoDB 支持 FindAndModify,再加上数组 $ 标识符(代表当前找到的数组元素),您可以在我认为是原子的单个操作中查找和更新文档的给定数组元素。至少,操作成功完成,没有错误,我们还没有遇到并发问题。 ;)
  • @jrista 你能举个例子吗?
  • 实际上,我相信可以通过标准更新直接更新数组元素:db.mycollection.update( { myarray : { $elemMatch : { someproperty : { $in : { "a", "b", "c" } } } } }, { $set : { 'myarray.$.otherproperty' : 567 } } ); 至于同时在数组上执行推/弹出/拉同时在一个原子语句中(这实际上是原始问题所要求的),我实际上并没有尝试过那个明确的任务(我不认为我第一次以同样的方式阅读了这个问题。)我认为 FindAndModify 会是更好的方式,虽然...
猜你喜欢
  • 1970-01-01
  • 2021-03-14
  • 2015-07-14
  • 2019-01-25
  • 2012-08-23
  • 2017-03-07
  • 1970-01-01
  • 2016-01-28
  • 2021-10-04
相关资源
最近更新 更多