mongodb php找到一个子对象并删除它,$ inc其他子对象

时间:2010-12-24 17:40:00

标签: php mongodb mongodb-php database

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

提前感谢您的帮助。

3 个答案:

答案 0 :(得分: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.fruitInventory1.apples,以简化下一个表达式。

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

要更新所有文档,您必须反复运行此代码,直到第一个findAndModify返回null(表示没有与查询匹配的文档)。

答案 1 :(得分:1)

使用$ unset进行多次更新:

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

在更高级别的注释中,您可能希望使用更丰富的数据类型(例如,通常应将整数存储为整数,除非它们没有充分的理由)。

答案 2 :(得分:0)

MongoDB不允许你修改文件的存在方案。对于这个任务你应该删除文件(或集合的元素)。并插入新修改的文​​档(或集合元素)