1

我有一个结构如下的文件:

{
    "_id" : 1000001,
    "ListMembers" : [
            {
                    "MemberID" : 1000,
                    "Notes" : "Test Notes for 1000"
            },
            {
                    "MemberID" : 1001,
                    "Notes" : "Test Notes for 1002"
            }
    ]

}

应用程序生成一个唯一 ID。我需要实现以下目标:

  1. 如果文档不存在,则插入带有数组字段的新文档。
  2. 如果文档存在于集合中并且成员记录存在于数组中,则更新成员注释
  3. 如果文档在集合中存在并且数组中不存在成员记录,则在数组中插入成员记录。

这里 #1 和 #2 工作正常,但 {upsert:true} 选项不适用于上面的 #3;如果文档存在但成员记录不存在,它会尝试插入具有相同 ID 的新文档,这显然会给我一个重复键错误。在这种情况下,MongoDB 是否支持 UPSERT 操作,或者我是否需要检查文档是否存在,然后对 #1 和 ($pull 和 $push) 执行 INSERT 以在数组字段上实现 #2 和 #3。

4

1 回答 1

0

当前不支持此操作,因为$ 位置运算符不支持更新插入:

不要将位置运算符 $ 用于 upsert 操作,因为插入将使用 $ 作为插入文档中的字段名称。

位置操作员需要更新成员记录的注释,但不适用于 upsert。

我建议的逻辑是进行更新查询以覆盖#2 和#3 - 我会确保writeconcern为 1 - 所以它返回更新的文档数。如果它没有返回,则插入 $push 项目到ListMembers- 这包括 #1*

*这里有一个潜在的竞争条件 - 对于额外的点,你应该确保当你尝试做$push它检查它不匹配方面并ListMembers设置 writeconcern。如果$push操作返回 0 - 这意味着文档在第一个操作和这个操作之间进行了更新,所以您现在可以继续返回,$update因为现在有一个匹配项,它将更新它。

于 2013-01-31T11:14:44.157 回答