“UPSERT”
问题描述:
目前,我有以下数据集:“UPSERT”
{
'component_id':1,
'_locales':[
{
'url': 'dutch',
'locale': 'nl_NL'
}
] (etc)
}
如果我想更新的语言环境我可以运行类似的东西行:
db.components.update(
{'component_id': 1, '_locales.locale': 'nl_NL'},
{$set: {'_locales.$': {'url': 'new url','locale':'nl_NL'}},
true
);
该作品直到现场不存在:
db.components.update(
{'component_id': 1, '_locales.locale': 'en_US'},
{$set: {'_locales.$': {'url': 'new url','locale':'en_US'}},
true
);
因为在component_id上有一个唯一的索引,所以会抛出一个excep抱怨一个重复的密钥。
有没有办法自动添加新的“文档”与不同的语言环境,并更新它,如果它已经存在?根据使用位置运算符的文档不能用'插入'。
答
您可以使用$addToSet添加到一个确保没有重复的数组元素,但这不适用于您的“更新”的情况。
为了做到你想要什么,你需要将你的数据结构更改为类似:
{
"_id" : ObjectId("4f9519d6684c8b1c9e72e367"),
"component_id" : 1,
"_locales" : {
"nl_NL" : {
"url" : "dutch"
}
}
}
现在你可以在nl_NL区域做一个更新只:
db.components.update({ component_id: 1 }, { $set: { '_locales.nl_NL.url' : 'new url' } }, true);
和新的语言环境也能发挥作用,比如有:
db.components.update({ component_id: 1 }, { $set: { '_locales.en_US.url' : 'American' } }, true);
您可能要consid呃到具有语言环境嵌套对象的一部分,以及也许,像:
{
"_id" : ObjectId("4f9519d6684c8b1c9e72e367"),
"component_id" : 1,
"_locales" : {
"nl_NL" : {
"url" : "dutch"
"locale" : "nl_NL"
}
}
}
这使得它更容易找回在某些情况下的数据。
嗨德里克,谢谢你的回复。你的建议实际上是我最初的数据结构,我改变了上述。一个原因是创建索引:_locales.url而不是在每个区域设置: _locales.nl_NL.url,_locales.en_US.url等 目前我通过获取所有_locales数据并修改/添加区域设置I '正在'手动'工作。当我完成后,我用新的替换当前的'_locales'。现在这样就足够了,表现明智这可能不是一个好主意。 – 2012-04-23 09:32:43
我也同意,由于索引的原因,使用“未定义”键通常不是一件好事。有时,如果由于其他情况下的索引/其他原因而提高性能,则最好是执行两次查询来执行更新。大部分时间没有真正的“正确方式”。玩它,如果它不执行更改它并运行两个查询更新。 – Derick 2012-04-23 12:35:35
@Derick:我正面临类似的问题。 http://stackoverflow.com/questions/32038606/defining-a-map-with-objectid-key-and-array-of-strings-as-value-in-mongoose-schem – 2015-08-17 10:45:29