【问题标题】:mongodb php finding a subobject and removing it, $inc other subobjectmongodb php 找到一个子对象并将其删除,$inc 其他子对象
【发布时间】:2010-12-24 17:39:59
【问题描述】:

我正在尝试从我的文档中删除子对象“apples”并更新“fruitInventory”属性,减少苹果的数量。

我对如何继续感到困惑,我应该使用点表示法还是对苹果进行全文搜索?我不知道这是否重要,但你可以假设苹果总是在字段 1 中。

// Document 1 
{
    "1": {
        "apples": 3,
        "fruitInventory": 21,
        "oranges": 12,
        "kiwis": 3,
        "lemons": 3
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 12,
        "oranges": 8,
    },
    "_id": "1"
}

// Document 2
{
    "1": {
        "apples": 5,
        "fruitInventory": 10,
        "oranges": 2,
        "pears": 3
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 6,
        "cherries": 2,
    },
    "_id": "2"
}

结果应该是这样的:

// Document 1 
{
    "1": {
        "fruitInventory": 18,
        "oranges": 12,
        "kiwis": 3,
        "lemons": "3"
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 12,
        "oranges": 8,
    },
    "_id": "1"
}

// Document 2
{
    "1": {
        "fruitInventory": 5,
        "oranges": "2",
        "pears": "3"
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 6,
        "cherries": 2,
    },
    "_id": "2"
}

提前感谢您的帮助。

【问题讨论】:

    标签: php mongodb mongodb-php database


    【解决方案1】:

    在 MongoDB 查询语言中,无法使用文档中的信息来更新文档。换句话说,没有办法用另一个属性的值来增加一个属性。具体来说:无法将 fruitInventory 增加 X,其中 X 是作为原子操作的 apples 属性的值。

    在避免竞争的同时,我实现这一点的方法是使用两个 findAndModify 操作(在 Mongo shell 语法中看到这里):

    var fruit = db.fruit.findAndModify({
     query: {locked: {$ne: true}, "1.apples": {$exists: true}},
     update: {$set: {locked: true}}
    });
    
    var fruitInventory = fruit["1"]["fruitInventory"];
    var apples = fruit["1"]["apples"];
    
    db.fruit.findAndModify({
      query: {"_id": fruit["_id"]},
      update: {
        $set: {"1.fruitInventory": fruitInventory + apples}, 
        $unset: {locked: false, "1.apples": true}
      }
    });
    

    发生的情况是这样的:首先我找到一个未锁定的文档(稍后会详细介绍),并且具有1.apples 属性。文档被返回并更新以获取 locked 属性作为单个原子操作。由于该文档现在有一个locked 属性,它不会被同一个查询找到,所以这个查询可以并行运行多次,而不会有修改同一个文档两次的风险。

    然后我提取1.fruitInventory1.apples,以简化下一个表达式。

    第二个findAndModify 使用新的总和更新1.fruitInventory 属性,并取消设置1.apples 属性以及locked 属性(将文档返回到其先前的未锁定状态)。

    要更新所有文档,您必须一遍又一遍地运行此代码,直到第一个 findAndModify 返回 null(意味着没有与查询匹配的文档)。

    【讨论】:

      【解决方案2】:

      使用 $unset 进行多次更新:

      > db.whatever.update({}, {$unset : {"1.apples" : true}}, false, true)
      

      在更高级的说明中,您可能希望使用更丰富的数据类型(例如,整数通常应该存储为整数,除非有充分的理由不这样做)。

      【讨论】:

      • 如何找到它所在的文档?感谢有关 int 的说明,已修复。
      • 这不会增加fruitInventory 属性,所以它不能解决问题。
      【解决方案3】:

      MongoDB 不允许您修改现有的文档方案。对于此任务,您应该删除文档(或集合的元素)。并插入新的修改文档(或集合元素)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-26
        • 2019-11-25
        • 1970-01-01
        • 1970-01-01
        • 2022-12-08
        • 2020-10-07
        • 2020-03-22
        • 1970-01-01
        相关资源
        最近更新 更多