【问题标题】:MongoDB Update array element (document with a key) if exists, else pushMongoDB更新数组元素(带有键的文档)如果存在,否则推送
【发布时间】:2019-07-10 12:32:29
【问题描述】:

我有这样的架构:

doc:
{
    //Some fields
    visits:
    [
        {
            userID: Int32
            time: Int64
        }
    ]

}

我想首先检查是否存在特定的userID,如果不存在,则使用该userID 和系统time 推送文档,否则只需更新time 值。我知道$push$addToSet 都无法做到这一点。同样使用$upsert:true 也不起作用,因为官方documentation 建议说DB 在尝试更新插入时将使用$ 作为字段名称而不是运算符。

请指导我。谢谢

【问题讨论】:

  • 看看这是否有帮助。 stackoverflow.com/a/41113069/2683814
  • 谢谢。这是一个两步查询。这不能只在一个查询中完成吗?
  • 这是我认为可能的唯一方法。对于顶级属性,您可以按照文档的建议进行一次查询。

标签: mongodb mongodb-query


【解决方案1】:

您可以使用$addToSet 向数组中添加一项,并使用$set 更新此数组中的现有项。

如果在数组中找不到userID,以下将向数组中添加一个新项:

db.doc.update({
    visits: {
        "$not": {
            "$elemMatch": {
                "userID": 4
            }
        }
    }
}, {
    $addToSet: {
        visits: {
            "userID": 4,
            "time": 1482607614
        }
    }
}, { multi: true });

如果匹配userId,以下将更新子文档数组项:

db.doc.update({ "visits.userID": 2 }, {
    $set: {
        "visits.$.time": 1482607614
    }
}, { multi: true });

【讨论】:

  • 但是这里我们必须执行两个查询。有没有单一查询的解决方案?
  • 很遗憾,这样的基本功能必须在两个查询中完成
  • 我同意多米尼克的观点。它可能会产生并发问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2014-07-29
  • 2019-09-15
  • 2016-02-25
  • 2019-08-04
相关资源
最近更新 更多