在使用MongoDB时,我似乎遇到了障碍,想知道是否有任何障碍而不必修改我的数据库结构。现在我的数据库结构如下:
Company=
{
_id:1,
properties:[
{
property_id: 1
tags : [
{
tag_id: 1
tag_value: 1000
channels: [
{
channel_id:1
channel_name:"test1"
},
{
channel_id:2
channel_name:"test2"
}]
},
{
tag_id:2
tag_value: 2500
channels: [
{
channel_id:2
channel_name:"test2"
},
{
channel_id:3
channel_name:"test3"
}]
}]
},
{
property_id: 2
tags : [
{
tag_id: 3
tag_value: 500
channels: [
{
channel_id:1
channel_name:"test1"
},
{
channel_id:3
channel_name:"test3"
}]
},
{
tag_id: 4
tag_value: 5000
channels: [
{
channel_id:1
channel_name:"test1"
}]
}]
}]
}
我遇到了一个问题,我无法找到更新属性中特定tag_ids的方法。例如,我想将属性2中tag_id 4的值更改为100.或者我想在tag_id 3中将通道添加到通道数组。
我想做的事情与此类似:
db.company.update({_id:1, "properties.property_id":2, "tags.tag_id":4}, {"properties.$.tags.$.tag_value":100});
但是我知道当前版本的MongoDB不支持它,它已经在JIRA中了。所以我的问题是,无论如何要更新文档的值,您需要指定两个不同的条件才能访问它。我知道我可以做properties.1.tags.0,但是我不知道我的数组的顺序,我的查询将以编程方式运行。
任何帮助都会很棒,甚至是我必须重组我的桌子的构造。
谢谢
答案 0 :(得分:1)
展平数组可能会导致相当大的文档,因为对于每个内部数组元素,其外部元素的所有数据都必须重复(对于所有级别都是如此)。
因此,如果flatten不是一个选项,那么在等待所提到的Jira(SERVER-831)中的增强功能时,这是一种解决方法:
根据你的例子,这将是这样的:
doc = db.xx.findOne( {_id:1} );
doc.properties.forEach( function(p) {
if ( p.property_id == 2 ) {
p.tags.forEach( function(t) {
if ( t.tag_id == 3 ) {
t.tag_value = 100;
}
else if ( t.tag_id == 4 ) {
newChannel = {};
newChannel.channel_id = 5;
newChannel.channel_name = "test5";
t.channels.push(newChannel);
}
})
}
});
db.xx.update({_id:1},{$set:{properties:doc.properties}});
结果是:
doc = db.xx.findOne({_id:1})
{
"_id" : 1,
"properties" : [
{
"property_id" : 1,
"tags" : [
{
"tag_id" : 1,
"tag_value" : 1000,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 2,
"channel_name" : "test2"
}
]
},
{
"tag_id" : 2,
"tag_value" : 2500,
"channels" : [
{
"channel_id" : 2,
"channel_name" : "test2"
},
{
"channel_id" : 3,
"channel_name" : "test3"
}
]
}
]
},
{
"property_id" : 2,
"tags" : [
{
"tag_id" : 3,
"tag_value" : 100,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 3,
"channel_name" : "test3"
}
]
},
{
"tag_id" : 4,
"tag_value" : 5000,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 5,
"channel_name" : "test5"
}
]
}
]
}
]
}