casting - MongoDb - Change type from Int to Double -
we have collection looks this:
{ "_id" : "10571:6", "v" : 261355, "ts" : 4.88387e+008 } now, of "v" ints, doubles. want change them doubles.
i've tried few things nothing works (v int32 record, want change double):
db.getcollection('vehiclelastvalues') .find ( {_id : "10572:6"} ) .foreach ( function (x) { temp = x.v * 1.0; db.getcollection('vehiclelastvalues').save(x); }} things i've tried:
x.v = x.v * 1.1 / 1.1; x.v = parsefloat (new string(x.v)); but can't saved double...
by default "numbers" stored "double" in mongodb unless cast overwise.
take following samples:
db.sample.insert({ "a": 1 }) db.sample.insert({ "a": numberlong(1) }) db.sample.insert({ "a": numberint(1) }) db.sample.insert({ "a": 1.223 }) this yields collection this:
{ "_id" : objectid("559bb1b4a23c8a3da73e0f76"), "a" : 1 } { "_id" : objectid("559bb1bba23c8a3da73e0f77"), "a" : numberlong(1) } { "_id" : objectid("559bb29aa23c8a3da73e0f79"), "a" : 1 } { "_id" : objectid("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 } despite different constructor functions note how several of data points there same. mongodb shell doesn't distinquish between them, there way can tell.
there of course $type query operator, allows selection of bson types.
so testing type 1 - "double":
> db.sample.find({ "a": { "$type": 1 } }) { "_id" : objectid("559bb1b4a23c8a3da73e0f76"), "a" : 1 } { "_id" : objectid("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 } you see both first insert , last selected, of course not other two.
so test bson type 16 - 32-bit integer
> db.sample.find({ "a": { "$type": 16 } }) { "_id" : objectid("559bb29aa23c8a3da73e0f79"), "a" : 1 } that "third" insertion used numberint() function in shell. function , other serialization driver can set specific bson type.
and bson type 18 - 64-bit integer
> db.sample.find({ "a": { "$type": 18 } }) { "_id" : objectid("559bb1bba23c8a3da73e0f77"), "a" : numberlong(1) } the "second" insertion contructed via numberlong().
if wanted "weed out" things "not double" do:
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]}) which other valid numeric types other "double" itself.
so "convert" these in collection, can "bulk" process this:
var bulk = db.sample.initializeunorderedbulkop(), count = 0; db.sample.find({ "$or": [ { "a": { "$type": 16 } }, { "a": { "$type": 18 } } ] }).foreach(function(doc) { bulk.find({ "_id": doc._id }) .updateone({ "$set": { "b": doc.a.valueof() } , "$unset": { "a": 1 } }); bulk.find({ "_id": doc._id }) .updateone({ "$rename": { "b": "a" } }); count++; if ( count % 1000 == 0 ) { bulk.execute() bulk = db.sample.initializeunorderedbulkop(); } }) if ( count % 1000 != 0 ) bulk.execute(); what performed in 3 steps "in bulk":
- re-cast value new field "double"
- remove old field unwanted type
- rename new field old field name
this necessary since bson type information "sticky" field element once created. in order "re-cast" need remove old data includes original field assignment.
so should explain how "detect" , "re-cast" unwanted types in documents.
Comments
Post a Comment