mongodb: update string field to integer
-
06-01-2021 - |
Frage
I have a collection that has some fields that should be integers. Due to a software bug, some of these values are strings. I need to convert them. Here is an example document:
var coll = db.getCollection('info');
coll.find({ id: "985517" });
Result:
{
"_id" : "41cbb4e48284c0612a1c4b3ee5e3e2720c01197a",
"id" : "985517",
"title" : "009_1a.jpg",
"ext" : ".jpg",
"content_type" : "image/jpeg; charset=utf-8",
"sha1" : "41cbb4e48284c0612a1c4b3ee5e3e2720c01197a",
"has_thumb" : true,
"size" : 2917,
"width_px" : "70",
"height_px" : "69"
}
I try to convert width_px and height_px values into integers. My first naive try:
var coll = db.getCollection('info');
var bulk = coll.initializeOrderedBulkOp();
var counter = 0;
coll.find({ width_px: { $type: "string" }, id: "985516" }).limit(100).forEach(function(data) {
var updoc = {
"$set": {}
};
updoc["$set"]["width_px"] = parseInt(data.width_px);
// queue the update
bulk.find({
"_id": data._id
}).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if (counter % 1000 == 0) {
bulk.execute();
bulk = coll.initializeOrderedBulkOp();
}
})
// Add the rest in the queue
if (counter % 1000 != 0) bulk.execute();
The result is dissapointing:
{
"_id" : "41cbb4e48284c0612a1c4b3ee5e3e2720c01197a",
"id" : "985517",
"title" : "009_1a.jpg",
"ext" : ".jpg",
"content_type" : "image/jpeg; charset=utf-8",
"sha1" : "41cbb4e48284c0612a1c4b3ee5e3e2720c01197a",
"has_thumb" : true,
"size" : 2917,
"width_px" : 70.0,
"height_px" : "69"
}
So it was updated to double, instead of int32. I understand that in JavaScript, there is no separate double and integer type, just "number". But I need to update 100 000 documents and I want to do this efficiently.
But how?
Lösung 2
The solution is to use NumberInt instead of parseInt.
var coll = db.getCollection('info');
var bulk = coll.initializeOrderedBulkOp();
var counter = 0;
coll.find({ width_px: { $type: "string" }}).forEach(function(data) {
var updoc = {
"$set": {}
};
updoc["$set"]["width_px"] = NumberInt(data.width_px);
// queue the update
bulk.find({
"_id": data._id
}).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if (counter % 1000 == 0) {
bulk.execute();
bulk = coll.initializeOrderedBulkOp();
}
})
// Add the rest in the queue
if (counter % 1000 != 0) bulk.execute();
It will construct a new NumberInt object that is mongodb specific, and it will be serialized as an int32.
Andere Tipps
As per MongoDB documentation here From the Documents tab
in MongoDB Compass
, you can view, insert, clone, modify, and delete documents .
First you have to connect your mongod with MongoDB Compass
then you shall able to change your desire data type of their respective field in MongoDB.
Change Field Type
You can change the data type of a field by using the data type selectors on the right of the field.
Note: Creating, deleting, editing and cloning documents is not permitted in MongoDB Compass Readonly Edition.
For your further ref here
change str to int
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = new NumberInt(obj.field-name);
db.db-name.save(obj); });