MongoDB tip, identify and convert type of a specific field
I found this post when I encountered some type issue and the better solution seems to be to convert the type in place.
So I just did a quick experiment myself to make sure it works properly.
to set up this experiment, first run
db.testConvert.insert({typeField:NumberLong(1)});
db.testConvert.insert({typeField:NumberInt(1)});
db.testConvert.insert({typeField:1});
We verify now typeField has contain all three types, Int64, Int32, and Double
Referencing from BSON type documentation, we know that Double is 1.
Then we run the following
var bulk = db.testConvert.initializeUnorderedBulkOp(),
count=0;
db.testConvert.find({"typeField":{"$type":1}}).forEach(function(doc) {
bulk.find({"_id":doc._id}).updateOne({
"$set":{"tmpField":NumberLong(doc.typeField.valueOf())},
"$unset":{"typeField":1}
});
bulk.find({"_id": doc._id}).updateOne({ "$rename": { "tmpField": "typeField" } });
count++;
if ( count % 1000 == 0 ) {
bulk.execute()
bulk = db.sample.initializeUnOrderedBulkOp();
}
})
if ( count % 1000 != 0 ) bulk.execute();
Note:
"typeField":{"$type":1} => to look for the type "double"
"$set":{"tmpField":NumberLong(doc.typeField.valueOf()) => get the value and convert to NumberLong to a temporary field
"$unset":{"typeField":1} => delete "typeField"
Now we can see the script has picked up the entry with type double and convert to NumberLong() as we had specified.
So I just did a quick experiment myself to make sure it works properly.
to set up this experiment, first run
db.testConvert.insert({typeField:NumberLong(1)});
db.testConvert.insert({typeField:NumberInt(1)});
db.testConvert.insert({typeField:1});
We verify now typeField has contain all three types, Int64, Int32, and Double
Referencing from BSON type documentation, we know that Double is 1.
Then we run the following
var bulk = db.testConvert.initializeUnorderedBulkOp(),
count=0;
db.testConvert.find({"typeField":{"$type":1}}).forEach(function(doc) {
bulk.find({"_id":doc._id}).updateOne({
"$set":{"tmpField":NumberLong(doc.typeField.valueOf())},
"$unset":{"typeField":1}
});
bulk.find({"_id": doc._id}).updateOne({ "$rename": { "tmpField": "typeField" } });
count++;
if ( count % 1000 == 0 ) {
bulk.execute()
bulk = db.sample.initializeUnOrderedBulkOp();
}
})
if ( count % 1000 != 0 ) bulk.execute();
Note:
"typeField":{"$type":1} => to look for the type "double"
"$set":{"tmpField":NumberLong(doc.typeField.valueOf()) => get the value and convert to NumberLong to a temporary field
"$unset":{"typeField":1} => delete "typeField"
Now we can see the script has picked up the entry with type double and convert to NumberLong() as we had specified.
Comments
Post a Comment