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

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

{
  id:"someId",
  date:Date
}

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

【问题讨论】:

    标签: arrays node.js mongodb subdocument


    【解决方案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不存在时添加新的子文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2015-05-26
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多