1

我正在尝试从我的文档中删除子对象“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"
}

在此先感谢您的帮助。

4

3 回答 3

2

在 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.fruitInventoryand1.apples来简化下一个表达式。

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

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

于 2010-12-31T11:09:52.040 回答
1

使用 $unset 进行多次更新:

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

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

于 2010-12-25T03:26:02.157 回答
0

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

于 2011-01-02T17:43:44.010 回答