我正在编写一个数据库层,其中1:n记录缓存在_children字段中。 所以,如果你有人:
{
id: 1,
name: 'Tony',
surname: 'Mobily',
_children: {
addresses: [],
}
},
{
name: 'Chiara',
surname: 'Mobily',
_children: {
addresses: [],
}
}
然后在地址中添加记录:
{
id: 100
personId: 1,
street: 'Some street',
country: 'Australia',
}
{
id: 101
personId: 1,
street: 'Some other street',
country: 'Australia',
}
正确的记录会在人物中自动更新:
{
id: 1,
name: 'Tony',
surname: 'Mobily',
_children: {
addresses: [
{
id: 100
personId: 1,
street: 'Some street',
country: 'Australia',
},
{
id: 101
personId: 1,
street: 'Some other street',
country: 'Australia',
}
],
}
},
我的图层还存储所有文本字段的UPPERCASE版本,并自动运行不区分大小写的搜索等。它还处理"查找"字段,自动填充它们。
当您在地址字段上进行批量更新时,它还会在" parent"上运行更新。字段,以便一切都同步。一切都很美妙。
除非您尝试对地址表进行MASS更新。
例如:
addresses.update( { country: 'Australia' }, { street: 'Something else' }, { multi: true } )
完成此操作后,我还会为每个"父母"运行查询。 table(在这种情况下,people
)这样:
people.update( { _children.country: 'Australia'}, { '_children.addresses.$.street': 'Something else' }, { multi: true } )
请注意" new"查询会自动解决。
但是,由于bug https://jira.mongodb.org/browse/SERVER-1243,我基本上搞砸了。
(注意插入总是一个操作,意味着一个简单的$ push(没有问题),而删除是一个需要$ pull on _children的操作($ pull接受一个过滤器来处理数组。所以,也没有问题。。唯一的问题是只有大规模更新。)
现在:
我无法加载完整的文档并手动更改所有条目有以下几个原因:(1)性能:我需要对每个匹配的记录运行更新,它可能是100万; (2)它实际上是不可能的,因为我没有办法重新运行"加载文档上的查询(可能涉及正则表达式等)
我无法重复更新操作,直到我获得ZERO更新(它们都已更改),因为如果更改是也匹配,它将永远执行(如果您改变' perth' perth2'并匹配以' p')开头的任何内容。
但是,我真的需要这个功能,而我却无法弄清楚如何去做。
你们有没有想法,除了请求MongoDB的人解决这个问题,这是Mongo阵列更新的又一个弱点?
答案 0 :(得分:2)
所以考虑到你是"批量更新"并且这可能是一次性操作,您可以考虑使用db.eval()
这样:
db.eval(function() {
db.collection.find({}).forEach(function(doc) {
doc._children.forEach(function(item) {
item.ucCountry = item.country.toUpperCase;
});
db.collection.update(
{ "_id": doc._id },
{ "$set": { "_children": doc._children } }
);
});
})
所以它几乎是标准循环,但这次它在服务器上运行。您甚至可以仅为要更改的数组元素添加$ set操作,以节省更多开销。
请注意阅读文档。您将锁定数据库进行写入,阻止所有其他JavaScript操作,例如" mapReduce"在执行更新期间。但这是最快的方法。