MongoDB 中我的复杂文档 update() 的解决问题是什么?
What is the addressing issue with my complex document update() in MongoDB?
我无法进入我的 MongoDB collection 并更改复杂文档中的值。我尝试了比下面显示的一个示例更多的变体,各种变体,但都失败了。
我想将键 "air" 的值从 "rain" 更改为 "clear"。在现实生活中,我不会知道 Key "air" 当前的 Value 是 "rain".
请注意,我没有使用 MongoDB _id Object 并且想在不使用它的情况下完成此操作。
weatherSys 中有 3 个文档 collection:
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"SanFrancisco" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
{
"_id" : ObjectId("58a638fb1831c61917f921c6"),
"LosAngeles" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
{
"_id" : ObjectId("58a638fb1831c61917f921c7"),
"SanDiego" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
var docKey = "LosAngeles";
var subKey = "air";
var newValue = "clear";
var query = {};
//var queryKey = docKey + ".$";
query[query] = subKey; // query = { }
var set = {};
var setKey = docKey + ".0." + subKey;
set[setKey] = newValue; // set = { "weather.0.air" : "clear" }
db.collection('weatherSys').update(query, { $set: set }, function(err, result) {
if (err) throw err;
});
更新一:
好的,所以我希望我能找到一个比你建议的更简单的布局,但我失败了。我尝试的所有内容都无法在 "air" 键级别寻址。所以我将你的 JSON 复制并粘贴到我的 collection 和 运行 中。我正在使用 MongoChef 来操作和测试 collection.
这是我的新布局,由粘贴您的 JSON 3 次以创建 3 个文档驱动:
然后当我尝试更新 "San Francisco" 文档的 "air" 键时,我得到了意想不到的结果。它没有更新 "air":"dry",而是在 "San Francisco" Object:
中创建了一个新的 "air" 键
所以我想好吧,让我们再次尝试更新,看看会发生什么:
如您所见,它更新了之前创建的 "air" 键。我可以解决这个问题并尝试让它以 "my" 的方式工作,但我只是想让它工作所以我再次重新配置我的 collection 布局,按照 "working":
并且运行再次更新:
然后我通过运行再次更新来验证它:
有效,我正在 multi-document 环境中正确更新。所以这是我目前的工作 collection 布局:
我对此有几个问题-
我在每个文档中都使用顶级密钥 "weather"。它不会对文档中的信息添加任何内容。是否有不需要该键及其带来的开销的布局设计更改?
假设我必须使用 "weather" 键。它的值是一个数组,但该数组只有一个元素,即 Object,其中包含键:city、sky、air 和 ground。寻址是否需要使用只有一个元素的数组?或者我可以摆脱它吗?设计可以 "weather":{} 而不是 "weather":[{}] 还是我会再次陷入不可寻址问题?
看来我现在可以更新()键的任何值:空气、天空和地面,但是 find() 结构是什么来读取键的值 "ground" 在其中一个文件中?
----> 好的,我想我有这个问题 #3-
db.weatherSys.find({ "weather.city" : "San Francisco" }, { "weather.ground": 1 })
- 在您建议的原始 collection 布局中,您能否向我解释一下为什么它没有像您和我预期的那样更新,而是创建了一个新的 "city" object?
这里有很多。感谢您的坚持。
不能使用位置运算符通过键查询数组。
您可以通过索引访问 weather
数组,但这意味着您知道数组索引。
例如,如果您要更新 weather
数组中的 air
元素值。
db.collection('weatherSys').update( {}, { $set: { "weather.1.air" : "clear"} } );
更新:
不幸的是,在不知道键的数组索引的情况下,我看不到任何更新值的方法。
您不需要查询对象,因为您的键是唯一的。
db.collection('weatherSys').update( {}, { $set: { "SanFrancisco.1.air" : "clear"} } );
或
其他变体,如果你想确保密钥存在。
db.collection('weatherSys').update( { "SanFrancisco": { $exists: true } }, { $set: { "SanFrancisco.1.air" : "clear"} } );
不确定是否可以,但是否可以将结构更新为以下内容。
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"weather" : [
{
"city": "LosAngeles",
"sky" : "grey" ,
"air" : "rain" ,
"ground" : "wet"
}
]
}
您现在可以使用 $positional
运算符进行更新。
db.collection('weatherSys').update( {"weather.city":"LosAngeles"}, { $set: { "weather.$.air" : "clear"} } );
I am using the top level Key "weather" in every document. It adds
nothing to the information within the document. Is there a layout
design change that would not necessitate that Key and the overhead it
brings along?
我能想到的唯一布局是将所有嵌入属性提升到顶层。抱歉,不知道为什么我第一次没有想到这一点。有时你只需要一个正确的问题就可以得到正确的答案。
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"city": "LosAngeles",
"sky" : "grey",
"air" : "rain",
"ground" : "wet"
}
所有更新都只是顶级更新。
db.collection('weatherSys').update( {"city":"LosAngeles"}, { $set: { "air" : "clear"} } );
Lets say I have to use the "weather" key. Its value is an array, but
that array only has one element, the Object which contains the Keys:
city, sky, air, and ground. Does addressing necessitate the use of an
array with only one element? Or could I get rid of it. Instead of
"weather":[{}] could the design be "weather":{} or would I get into
non addressability issues again?
N/A 如果您同意第一个建议。
It appears I can now update() any of the Values for the Keys: air,
sky, and ground, but what is the find() structure to say READ the
Value of the Key "ground" in one of the documents?
db.weatherSys.find({ "city" : "San Francisco" }, { "ground": 1 })
In the original collection layout that you had suggested, could you
explain to me why it did not update as you and I had expected but
instead created a new the "city" object?
那是复制粘贴错误。我的意思是建议您现在的工作布局。更新了我之前的布局。
我无法进入我的 MongoDB collection 并更改复杂文档中的值。我尝试了比下面显示的一个示例更多的变体,各种变体,但都失败了。
我想将键 "air" 的值从 "rain" 更改为 "clear"。在现实生活中,我不会知道 Key "air" 当前的 Value 是 "rain".
请注意,我没有使用 MongoDB _id Object 并且想在不使用它的情况下完成此操作。
weatherSys 中有 3 个文档 collection:
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"SanFrancisco" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
{
"_id" : ObjectId("58a638fb1831c61917f921c6"),
"LosAngeles" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
{
"_id" : ObjectId("58a638fb1831c61917f921c7"),
"SanDiego" : [
{ "sky" : "grey" },
{ "air" : "rain" },
{ "ground" : "wet" }
]
}
var docKey = "LosAngeles";
var subKey = "air";
var newValue = "clear";
var query = {};
//var queryKey = docKey + ".$";
query[query] = subKey; // query = { }
var set = {};
var setKey = docKey + ".0." + subKey;
set[setKey] = newValue; // set = { "weather.0.air" : "clear" }
db.collection('weatherSys').update(query, { $set: set }, function(err, result) {
if (err) throw err;
});
更新一: 好的,所以我希望我能找到一个比你建议的更简单的布局,但我失败了。我尝试的所有内容都无法在 "air" 键级别寻址。所以我将你的 JSON 复制并粘贴到我的 collection 和 运行 中。我正在使用 MongoChef 来操作和测试 collection.
这是我的新布局,由粘贴您的 JSON 3 次以创建 3 个文档驱动:
然后当我尝试更新 "San Francisco" 文档的 "air" 键时,我得到了意想不到的结果。它没有更新 "air":"dry",而是在 "San Francisco" Object:
中创建了一个新的 "air" 键所以我想好吧,让我们再次尝试更新,看看会发生什么:
如您所见,它更新了之前创建的 "air" 键。我可以解决这个问题并尝试让它以 "my" 的方式工作,但我只是想让它工作所以我再次重新配置我的 collection 布局,按照 "working":
并且运行再次更新:
然后我通过运行再次更新来验证它:
有效,我正在 multi-document 环境中正确更新。所以这是我目前的工作 collection 布局:
我对此有几个问题-
我在每个文档中都使用顶级密钥 "weather"。它不会对文档中的信息添加任何内容。是否有不需要该键及其带来的开销的布局设计更改?
假设我必须使用 "weather" 键。它的值是一个数组,但该数组只有一个元素,即 Object,其中包含键:city、sky、air 和 ground。寻址是否需要使用只有一个元素的数组?或者我可以摆脱它吗?设计可以 "weather":{} 而不是 "weather":[{}] 还是我会再次陷入不可寻址问题?
看来我现在可以更新()键的任何值:空气、天空和地面,但是 find() 结构是什么来读取键的值 "ground" 在其中一个文件中?
----> 好的,我想我有这个问题 #3- db.weatherSys.find({ "weather.city" : "San Francisco" }, { "weather.ground": 1 })
- 在您建议的原始 collection 布局中,您能否向我解释一下为什么它没有像您和我预期的那样更新,而是创建了一个新的 "city" object?
这里有很多。感谢您的坚持。
不能使用位置运算符通过键查询数组。
您可以通过索引访问 weather
数组,但这意味着您知道数组索引。
例如,如果您要更新 weather
数组中的 air
元素值。
db.collection('weatherSys').update( {}, { $set: { "weather.1.air" : "clear"} } );
更新:
不幸的是,在不知道键的数组索引的情况下,我看不到任何更新值的方法。
您不需要查询对象,因为您的键是唯一的。
db.collection('weatherSys').update( {}, { $set: { "SanFrancisco.1.air" : "clear"} } );
或
其他变体,如果你想确保密钥存在。
db.collection('weatherSys').update( { "SanFrancisco": { $exists: true } }, { $set: { "SanFrancisco.1.air" : "clear"} } );
不确定是否可以,但是否可以将结构更新为以下内容。
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"weather" : [
{
"city": "LosAngeles",
"sky" : "grey" ,
"air" : "rain" ,
"ground" : "wet"
}
]
}
您现在可以使用 $positional
运算符进行更新。
db.collection('weatherSys').update( {"weather.city":"LosAngeles"}, { $set: { "weather.$.air" : "clear"} } );
I am using the top level Key "weather" in every document. It adds nothing to the information within the document. Is there a layout design change that would not necessitate that Key and the overhead it brings along?
我能想到的唯一布局是将所有嵌入属性提升到顶层。抱歉,不知道为什么我第一次没有想到这一点。有时你只需要一个正确的问题就可以得到正确的答案。
{
"_id" : ObjectId("58a638fb1831c61917f921c5"),
"city": "LosAngeles",
"sky" : "grey",
"air" : "rain",
"ground" : "wet"
}
所有更新都只是顶级更新。
db.collection('weatherSys').update( {"city":"LosAngeles"}, { $set: { "air" : "clear"} } );
Lets say I have to use the "weather" key. Its value is an array, but that array only has one element, the Object which contains the Keys: city, sky, air, and ground. Does addressing necessitate the use of an array with only one element? Or could I get rid of it. Instead of "weather":[{}] could the design be "weather":{} or would I get into non addressability issues again?
N/A 如果您同意第一个建议。
It appears I can now update() any of the Values for the Keys: air, sky, and ground, but what is the find() structure to say READ the Value of the Key "ground" in one of the documents?
db.weatherSys.find({ "city" : "San Francisco" }, { "ground": 1 })
In the original collection layout that you had suggested, could you explain to me why it did not update as you and I had expected but instead created a new the "city" object?
那是复制粘贴错误。我的意思是建议您现在的工作布局。更新了我之前的布局。