回答:
$type
データのを変更する唯一の方法は、データのタイプが正しいデータを更新することです。
この場合、$type
を1(double)から2(string)に変更しようとしているようです。
したがって、DBからドキュメントをロードし、キャスト(new String(x)
)を実行してから、ドキュメントを再度保存します。
これをプログラムで完全にシェルから行う必要がある場合は、find(...).forEach(function(x) {})
構文を使用できます。
以下の2番目のコメントへの応答。フィールドbad
を数値からコレクション内の文字列に変更しますfoo
。
db.foo.find( { 'bad' : { $type : 1 } } ).forEach( function (x) {
x.bad = new String(x.bad); // convert field to string
db.foo.save(x);
});
new String(x.bad)
、0-index-item x.bad
値を持つ文字列のコレクションを作成します。""+x.bad
Simoneによって記述されたバリアントは期待通りに機能します-Int32の代わりに文字列値を作成します
db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
文字列フィールドを整数に変換します。
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = new NumberInt(obj.field-name);
db.db-name.save(obj);
});
整数フィールドを文字列に変換します。
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = "" + obj.field-name;
db.db-name.save(obj);
});
NumberLong
、ここのように:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
文字列から整数への変換用。
db.my_collection.find().forEach( function(obj) {
obj.my_value= new NumberInt(obj.my_value);
db.my_collection.save(obj);
});
文字列から二重変換へ。
obj.my_value= parseInt(obj.my_value, 10);
フロートの場合:
obj.my_value= parseFloat(obj.my_value);
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
new NumberInt()
を開始するMongo 4.2
とdb.collection.update()
、集約パイプラインを受け入れることができ、最終的に独自の値に基づいてフィールドを更新できます。
// { a: "45", b: "x" }
// { a: 53, b: "y" }
db.collection.update(
{ a : { $type: 1 } },
[{ $set: { a: { $toString: "$a" } } }],
{ multi: true }
)
// { a: "45", b: "x" }
// { a: "53", b: "y" }
最初の部分{ a : { $type: 1 } }
は一致クエリです:
"a"
値がdoubleのときに文字列に変換するため、これ"a"
はタイプ1
(double)の要素に一致します。2番目の部分[{ $set: { a: { $toString: "$a" } } }]
は、更新集約パイプラインです。
$set
Mongo 4.2
この場合、フィールドを変更する新しい集計演算子()です。"$set"
の値"a"
に"$a"
変換しました"$toString"
。Mongo 4.2
、ドキュメントを更新するときにドキュメント自体を参照できることです。新しい値"a"
はの既存の値に基づいています"$a"
。"$toString"
、で導入された新しい集計演算子についても注意してくださいMongo 4.0
。忘れないでください{ multi: true }
。そうしないと、最初に一致したドキュメントのみが更新されます。
場合は、あなたのキャストがない、二重の文字列に、あなたはで導入されたさまざまな変換演算子の間の選択持っているMongo 4.0
ように$toBool
、$toInt
...
また、対象のタイプに専用のコンバーターがない場合は、次{ $toString: "$a" }
の$convert
操作で置き換えることができます。{ $convert: { input: "$a", to: 2 } }
ここで、の値to
は次の表にあります。
db.collection.update(
{ a : { $type: 1 } },
[{ $set: { a: { $convert: { input: "$a", to: 2 } } } }],
{ multi: true }
)
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )
-次multi : true
を使用して回避できますupdateMany
これまでのすべての回答では、forEachの一部のバージョンを使用して、クライアント側のすべてのコレクション要素を繰り返し処理しています。
ただし、次のように集約パイプラインと$ outステージを使用することで、MongoDBのサーバー側処理を使用できます。
$ outステージは、既存のコレクションをアトミックに新しい結果コレクションに置き換えます。
例:
db.documents.aggregate([
{
$project: {
_id: 1,
numberField: { $substr: ['$numberField', 0, -1] },
otherField: 1,
differentField: 1,
anotherfield: 1,
needolistAllFieldsHere: 1
},
},
{
$out: 'documents',
},
]);
文字列型のフィールドを日付フィールドに変換するには、find()
メソッドを使用してforEach()
メソッドから返されたカーソルを反復処理し、ループ内でフィールドをDateオブジェクトに変換してから、$set
演算子を使用してフィールドを更新する必要があります。
一括更新にBulk APIを使用して、パフォーマンスを向上させます。たとえば、1000のバッチでサーバーに操作を送信します。これにより、すべてのリクエストをサーバーに送信するのではなく、すべてのリクエストをサーバーに送信するのではなく、パフォーマンスが向上します。 1000リクエスト。
以下はこのアプローチを示しています>= 2.6 and < 3.2
。最初の例では、MongoDBバージョンで利用可能なBulk APIを使用しています。すべてのcreated_at
フィールドを日付フィールドに変更することにより、コレクション内のすべてのドキュメントを更新します。
var bulk = db.collection.initializeUnorderedBulkOp(),
counter = 0;
db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
var newDate = new Date(doc.created_at);
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "created_at": newDate}
});
counter++;
if (counter % 1000 == 0) {
bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
bulk = db.collection.initializeUnorderedBulkOp();
}
})
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }
次の例は、MongoDBの新しいバージョンに適用されます。3.2
これは、Bulk APIを非推奨にし、次を使用して新しいAPIセットを提供していますbulkWrite()
。
var bulkOps = [];
db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
var newDate = new Date(doc.created_at);
bulkOps.push(
{
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "created_at": newDate } }
}
}
);
})
db.collection.bulkWrite(bulkOps, { "ordered": true });
コレクション内の複数のフィールドのデータ型を変更する必要があるため、以下を使用して、ドキュメントのコレクションで複数のデータ型を変更しました。古い質問に答えますが、他の人に役立つかもしれません。
db.mycoll.find().forEach(function(obj) {
if (obj.hasOwnProperty('phone')) {
obj.phone = "" + obj.phone; // int or longint to string
}
if (obj.hasOwnProperty('field-name')) {
obj.field-name = new NumberInt(obj.field-name); //string to integer
}
if (obj.hasOwnProperty('cdate')) {
obj.cdate = new ISODate(obj.cdate); //string to Date
}
db.mycoll.save(obj);
});
You can easily convert the string data type to numerical data type.
Don't forget to change collectionName & FieldName.
for ex : CollectionNmae : Users & FieldName : Contactno.
このクエリを試してください。
db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});
デモでは、mongooseを使用してフィールドmidのタイプを文字列からmongoのobjectIdに変更します
Post.find({}, {mid: 1,_id:1}).exec(function (err, doc) {
doc.map((item, key) => {
Post.findByIdAndUpdate({_id:item._id},{$set:{mid: mongoose.Types.ObjectId(item.mid)}}).exec((err,res)=>{
if(err) throw err;
reply(res);
});
});
});
Mongo ObjectIdは、次のようなスタイルのもう1つの例です。
答えが他の人の役に立つことを期待する数値、文字列、ブール値。
文字列から浮動小数点への変換にmongodbコンソールでこのスクリプトを使用しています...
db.documents.find({ 'fwtweaeeba' : {$exists : true}}).forEach( function(obj) {
obj.fwtweaeeba = parseFloat( obj.fwtweaeeba );
db.documents.save(obj); } );
db.documents.find({ 'versions.0.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) {
obj.versions[0].content.fwtweaeeba = parseFloat( obj.versions[0].content.fwtweaeeba );
db.documents.save(obj); } );
db.documents.find({ 'versions.1.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) {
obj.versions[1].content.fwtweaeeba = parseFloat( obj.versions[1].content.fwtweaeeba );
db.documents.save(obj); } );
db.documents.find({ 'versions.2.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) {
obj.versions[2].content.fwtweaeeba = parseFloat( obj.versions[2].content.fwtweaeeba );
db.documents.save(obj); } );
そしてこれはphp)))で
foreach($db->documents->find(array("type" => "chair")) as $document){
$db->documents->update(
array('_id' => $document[_id]),
array(
'$set' => array(
'versions.0.content.axdducvoxb' => (float)$document['versions'][0]['content']['axdducvoxb'],
'versions.1.content.axdducvoxb' => (float)$document['versions'][1]['content']['axdducvoxb'],
'versions.2.content.axdducvoxb' => (float)$document['versions'][2]['content']['axdducvoxb'],
'axdducvoxb' => (float)$document['axdducvoxb']
)
),
array('$multi' => true)
);
}
私の場合、私は以下を使用します
function updateToSting(){
var collection = "<COLLECTION-NAME>";
db.collection(collection).find().forEach(function(obj) {
db.collection(collection).updateOne({YOUR_CONDITIONAL_FIELD:obj.YOUR_CONDITIONAL_FIELD},{$set:{YOUR_FIELD:""+obj.YOUR_FIELD}});
});
}
toString
ドキュメントのフィールドにいる必要がある場合は、これが私が作成/使用した小さなプログラムです。