我正在尝试从我的文档中删除子对象'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"
}
提前感谢您的帮助。
答案 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.fruitInventory
和1.apples
,以简化下一个表达式。
第二个findAndModify
使用新总和更新1.fruitInventory
属性,并取消设置1.apples
属性以及locked
属性(将文档返回到其中)以前,解锁,状态)。
要更新所有文档,您必须反复运行此代码,直到第一个findAndModify
返回null
(表示没有与查询匹配的文档)。
答案 1 :(得分:1)
使用$ unset进行多次更新:
> db.whatever.update({}, {$unset : {"1.apples" : true}}, false, true)
在更高级别的注释中,您可能希望使用更丰富的数据类型(例如,通常应将整数存储为整数,除非它们没有充分的理由)。
答案 2 :(得分:0)
MongoDB不允许你修改文件的存在方案。对于这个任务你应该删除文件(或集合的元素)。并插入新修改的文档(或集合元素)