我正在尝试使用其他NumberLong值更新我的一个集合中的某些NumberLong类型值。以下是我的收藏结构:
{
"_id" : ObjectId("55e57337d4c6cf80e68b1fe3"),
"tenantId" : NumberLong(7),
"refId" : NumberLong(20),
"refIdentifierName" : "resourceInstanceId",
"config" : {
"contract" : {
"contractLength" : "12 months",
"startDate" : "2015-01-21T09:36:39+00:00",
"billingFrequency" : "monthly",
"margin" : 9,
"endDate" : "2016-01-21T09:36:39+00:00"
}
}
让我们说这里我试图更新所有tenantId值7到8。
这是我正在使用的脚本:
var cursor = db.resourceInstanceConfiguration.find();
while (cursor.hasNext()) {
var x = cursor.next();
x['tenantId'] = x['tenantId'].replace('7','8');
db.resourceInstanceConfiguration.update({_id : x._id}, x);
}
获取错误:TypeError: Object NumberLong(6) has no method 'replace'
答案 0 :(得分:4)
您可以使用以下查询来实现此目的:
yourString.startsWith("not")
答案 1 :(得分:3)
似乎有些人很快就提出了另一个答案而没有意识到它不可行,也不是一个很好的解释。
这里的两个问题是你基本上需要"循环"结果是为了读取您想要更改的值,然后将其写回。这可能最好用"Bulk" operations来处理,最好在shell下作为脚本之一来处理。
" next"问题是这里的BSON类型信息是"粘性"并且您不能简单地将值更改为代码中的普通双精度并将其写回。你需要实际"删除"该字段完全来自文档"之前"你可以回写转换后的价值。
同样,整个过程也适用于批量操作,如下所示:
var bulk = db.resourceInstanceConfiguration.initializeOrderedBulkOp(),
count = 0;
db.junk.find({
"$or": [
{ "tenantId": { "$type": 18 } },
{ "refId": { "$type": 18 } }
]
}).forEach(function(doc) {
print(doc.a.valueOf());
bulk.find({ "_id": doc._id }).updateOne({
"$unset": { "tenantId": "", "refId": "" }
});
bulk.find({ "_id": doc._id }).updateOne({
"$set": {
"tenantId": doc.tenantId.valueOf(),
"refId": doc.tenantId.valueOf()
}
});
count += 2;
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.resourceInstanceConfiguration.initializeOrderedBulkOp();
}
});
if ( count % 1000 != 0 )
bulk.execute();
因此,您基本上$unset
首先删除该字段的BSON数据的所有跟踪,并删除具有新值的$set
。
然后,所有值都将成为标准" double"或BSON类型1也由$type
运营商确认。