MongoDB更新数组元素(带有键的文档)如果存在,否则推送

Posted

技术标签:

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

我有这样的架构:

doc:

    //Some fields
    visits:
    [
        
            userID: Int32
            time: Int64
        
    ]


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

请指导我。谢谢

【问题讨论】:

看看这是否有帮助。 ***.com/a/41113069/2683814 谢谢。这是一个两步查询。这不能只在一个查询中完成吗? 这是我认为可能的唯一方法。对于***属性,您可以按照文档的建议进行一次查询。 【参考方案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 );

【讨论】:

但是这里我们必须执行两个查询。有没有单一查询的解决方案? 很遗憾,这样的基本功能必须在两个查询中完成 我同意多米尼克的观点。它可能会产生并发问题。

以上是关于MongoDB更新数组元素(带有键的文档)如果存在,否则推送的主要内容,如果未能解决你的问题,请参考以下文章

mongodb:如果元素不存在,则updateOne设置字符串数组,如果存在则保持不变

MongoDB 中嵌入文档的数组元素的并发更新

MongoDB-更新多个文档解决方案-更新文档计数器或在不存在的情况下插入

获取数组中每个索引的子文档元素计数并更新子文档键 - 数组中的子文档(IN MONGODB)

MongoDB - 仅当嵌套数组中的所有条目存在时才更新它们

Mongodb怎样更新像这样的文档,数组里面有子文档