Reputation: 790
I am trying to update some NumberLong type value in one of my collection with some other NumberLong value. Below is my collection structure :
{
"_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"
}
}
Lets say here i am trying to update all tenantId with value 7 to 8.
This is the script i am using :
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);
}
Getting error : TypeError: Object NumberLong(6) has no method 'replace'
Upvotes: 3
Views: 1488
Reputation: 50406
Seems some people were very quick to upvote another answer without realizing it cannot possibly work, nor is it a very good explanation.
The two problems here are that you basically need to "loop" the results in order to read the values you want to change and then write them back. This is probably best handled with "Bulk" operations and best done under the shell as a one of script.
The "next" problem is the BSON type information here is "sticky" and that you cannot simply change the value to an plain double in code and write it back. You need to actually "remove" the field completely from the document "before" you can write back a converted value.
Again the whole process lends well to bulk operations as follows:
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();
So you essentially $unset
first to remove all trace for the BSON data for the field and the $set
with the new value.
All values will then be a standard "double" or BSON type 1 as also confirmed by the $type
operator.
Upvotes: 3
Reputation: 58
You can do achieve this by using the following query:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
db.collectionName.update({<field>:<value>},{$set:{<field>:<New Value>}},<upsert>,<multi>);
Upvotes: 4