【问题标题】:MongoDB: Add and remove from array field at the same timeMongoDB:同时从数组字段中添加和删除
【发布时间】:2017-01-26 18:08:17
【问题描述】:

我想重命名我们文档的 tags 数组中的标签,例如将集合中的所有标签a 更改为c。文件看起来像这样:

[ { _id: …, tags: ['a', 'b', 'c'] },
  { _id: …, tags: ['a', 'b'] },
  { _id: …, tags: ['b', 'c', 'd'] } ]

我需要保持标签唯一。这意味着,这样的更新将不起作用,因为第一个文档最终将包含标签 c 两次

db.docs.update(
    { tags: 'a' },
    { $set: { 'tags.$': 'c' } }
)

所以,我也尝试了这个:

db.docs.update(
    { tags: 'a' },
    {
        $pull: { 'a' },
        $addToSet: { 'c' }
    }
)

但这给出了MongoError: Cannot update 'tags' and 'tags' at the same time

是否有机会通过一次更新重命名标签?

【问题讨论】:

标签: mongodb


【解决方案1】:

根据official MongoDB documentation,没有办法表达对一组元素的“替换”操作。所以我想,没有办法在一次更新中做到这一点。

更新: 经过一番调查,我发现了this 文件。如果我理解正确,您的查询应该如下所示:

db.docs.update({
       tags: 'a'
  }, {
    $set: { 'tags.$': 'c'}
  })

其中 'tags.$' 表示 "tags" 数组中与查询匹配的第一个元素的选择器,因此它将第一次出现的 'a' 替换为 'c'。据我了解,您的“标签”数组不包含重复项,因此第一个匹配项将是唯一匹配项。

【讨论】:

  • 感谢您的回复。关于您的更新:这是我首先尝试的。但它会创建重复:如果c已经在数组中,a将被重命名为c,并且数组中有两个c
  • 啊!看来我错过了那部分。然后我想我的答案的第一部分适用,它表明您无法在单一操作中清楚地表达该意图。我不太清楚 mongodb update doc 是否可以包含嵌套查询。即使可以,那写起来也挺麻烦的,因为你需要表达的是“distinct(union(minus($row.tags, ['a']), ['c']) )”, in sql 术语,即使在这种简化形式下也看起来很痛苦。
  • 我想我当时想说的是,您必须首先在包含“a”的任何地方添加一个“c”元素,然后运行第二个更新以删除“a” '。
  • 这就是我所拥有的,但我希望有一些更优雅的解决方案 :) 但是您的反馈和上面链接的旧问题也证实了这是要走的路。谢谢!
猜你喜欢
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多