【发布时间】:2014-08-15 09:20:37
【问题描述】:
我想将所有“组织”的“状态”字段转换为所有大写字母。所以
“Ky”变成“KY” 'tX' 变成 'TX' 'ca' 变成 'CA'
为什么这不起作用
db.organizations.update(state:{ $exists : true }},{$set:{state:{ $toUpper : state }}}, false, true)
【问题讨论】:
我想将所有“组织”的“状态”字段转换为所有大写字母。所以
“Ky”变成“KY” 'tX' 变成 'TX' 'ca' 变成 'CA'
为什么这不起作用
db.organizations.update(state:{ $exists : true }},{$set:{state:{ $toUpper : state }}}, false, true)
【问题讨论】:
您引用的$toLower 和$toUpper 运算符仅用于aggregation framework,并且其本身不会像.update() 语句那样更改集合中的文档。此外,目前还不能在更新语句中引用现有字段的值来生成新值。
您需要做的是“循环”集合并进行更改:
db.organizations.find({ "state": { "$exists": true } }).forEach(function(doc) {
db.organizations.update(
{ "_id": doc._id },
{ "$set": { "state": doc.state.toUpperCase() } }
);
});
在 MongoDB 2.6 或更高版本中,您可以使用批量操作 API 使这一点变得更好:
var bulk = db.organizations.initializeOrderedBulkOp();
var count = 0;
db.organizations.find({ "state": { "$exists": true } }).forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "state": doc.state.toUpperCase() } }
);
count++;
if ( count % 500 == 0 ) {
bulk.execute();
bulk = db.organizations.initializeOrderedBulkOp();
count = 0;
}
});
if ( count > 0 )
bulk.execute();
虽然仍然基本上循环结果,但每 500 个文档或您选择设置的任何内容都只会将写入发送到数据库一次,并保持在操作的 16MB BSON 限制之下。
【讨论】:
toUpper() 是为字符串类型对象内置的 JavaScript。我们已经检查过它是否存在,那么您的某些数据是否有可能实际上是 null 或者不是字符串?您实际上是在声明doc 变量的.forEach() 循环中运行它吗?基本代码已经完成了数千次,所以它确实有效。检查你在做什么。
String.prototype.toUpperCase()。
你必须像这样输入toUpperCase():
"$set": { "state": doc.state.toUpperCase() } }
【讨论】: