デフォルトでは、一般的に過度にキャストされない限り、すべての「数値」は「double」としてMongoDBに格納されます。
次のサンプルを取ります:
db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })
これにより、次のようなコレクションが生成されます。
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
コンストラクター関数が異なるにもかかわらず、そこにあるいくつかのデータポイントがほとんど同じように見えることに注意してください。 MongoDBシェル自体は、必ずしもそれらを明確に区別するわけではありませんが、それを判断する方法があります。
もちろん、 $type
もあります クエリ演算子。BSONタイプを選択できます。
したがって、これをタイプ1でテストします-これは「ダブル」です:
> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
最初の挿入と最後の挿入の両方が選択されていることがわかりますが、もちろん他の2つは選択されていません。
では、32ビット整数であるBSONタイプ16をテストします
> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
これは、NumberInt()
を使用した「3番目の」挿入でした。 シェルで機能します。そのため、ドライバーからの関数やその他のシリアル化により、この特定のBSONタイプを設定できます。
そして、BSONタイプ18の場合-これは64ビット整数です
> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
NumberLong()
を介して作成された「2番目の」挿入 。
「ダブルではない」ものを「取り除く」場合は、次のようにします。
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})
「double」自体以外の有効な数値タイプはこれだけです。
したがって、コレクション内のこれらを「変換」するには、次のように「一括」処理することができます。
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();
それは「まとめて」3つのステップで実行されます:
- 値を「double」として新しいフィールドに再キャストします
- 不要なタイプの古いフィールドを削除します
- 新しいフィールドの名前を古いフィールド名に変更します
これは必要です BSONタイプ情報は、作成されたフィールド要素に「スティッキー」であるためです。したがって、「再キャスト」するには、元のフィールド割り当てを含む古いデータを完全に削除する必要があります。
これで、ドキュメント内の不要なタイプを「検出」および「再キャスト」する方法が説明されます。