只有在满足条件的情况下,有没有办法将子文档推送到 mongodb 数组中?

Posted

技术标签:

【中文标题】只有在满足条件的情况下,有没有办法将子文档推送到 mongodb 数组中?【英文标题】:Is there a way to push a sub document into mongodb array only if the condition is satisfied? 【发布时间】:2016-09-20 02:35:24 【问题描述】:

我正在将子文档推送到一个数组中。 基本上子文档是这样的:


  id:"someId",
  date:Date

我只想在没有其他子文档与匹配 id 的情况下添加新的子文档。我在 mongodb 文档上找到了$addToSet 修饰符,但我不确定它是否可以只检查子文档中的键而不是比较整个数组项目到另一个。 有什么方法可以在单个查询中执行此操作,还是我应该使用 2 个查询?

【问题讨论】:

【参考方案1】:

您可以在单个原子更新操作中执行此操作。假设您的收藏有以下文档:

蒙古壳

db.test.insert([
     
        "_id": 1,
        "items": [
             "id": 1, "date": new Date("2016-05-20") ,
             "id": 2, "date": new Date("2016-05-21") 
        ]
    ,
     
        "_id": 2,
        "items": [
             "date": new Date("2016-05-22") 
        ]
    
])

然后 mongo shell 中的以下更新语句将通过将新的子文档 "id": 3, "date": new Date() 添加到 items 数组来更新具有 items 子文档但没有 id 键的文档:

db.test.update(
     "items.id":  "$exists": false  ,
    
        "$push": 
            "items":  "id": 3, "date": new Date() 
        
    
)

查询测试集合

> db.test.find().pretty()

        "_id" : 1,
        "items" : [
                
                        "id" : 1,
                        "date" : ISODate("2016-05-20T00:00:00Z")
                ,
                
                        "id" : 2,
                        "date" : ISODate("2016-05-21T00:00:00Z")
                
        ]


        "_id" : 2,
        "items" : [
                
                        "date" : ISODate("2016-05-22T00:00:00Z")
                ,
                
                        "id" : 3,
                        "date" : ISODate("2016-05-23T09:33:15.913Z")
                
        ]
    

仅当没有其他子文档具有匹配的 id 时才添加新的子文档,您只需要一个更新操作即可指定匹配条件 在更新查询文档中。

下面的更新操作会将带有id = 4 的子文档添加到数组中,因为现有文档中没有匹配的数组元素:

db.test.update(
     "items.id":  "$ne": 4  ,
    
        "$push": 
            "items":  "id": 4, "date": new Date() 
        
    
)

对于您只想添加子文档的独占更新,如果存在 id 字段并且给定的 id 不匹配,则将条件与相等检查一起包含:

db.test.update(
     
        "items.id":  
            "$exists": true,
            "$ne": 4 
         
    ,
    
        "$push": 
            "items":  "id": 4, "date": new Date() 
        
    
)

【讨论】:

我说的是只有在没有匹配的 id 时才推入数组 @nikoss 在您更改问题的方式上,这被认为是一种不好的做法; 只有在 id 不存在时我才想添加新的子文档。我只想在没有其他具有匹配 id 的子文档时添加新的子文档。上面的答案直接解决了原始问题我只想在id不存在时添加新的子文档。

以上是关于只有在满足条件的情况下,有没有办法将子文档推送到 mongodb 数组中?的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs,我正在尝试将子对象推送到数组

如何在不推送到服务器的情况下更新中继存储

数据推送到 Snowflake 阶段时触发 Snowflake 任务

GCP - 谷歌云平台:有没有任何方法可以在没有任何版本控制系统的情况下将代码从 eclipse 推送到云端?

在 mongodb 的一次更新调用中推送到两个单独的数组

在没有证书的情况下将 iPhone 应用程序侧加载到设备