ฉันพยายามที่จะเปลี่ยนประเภทของเขตข้อมูลจากภายในเปลือก Mongo
ฉันกำลังทำสิ่งนี้ ...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
แต่มันไม่ทำงาน!
ฉันพยายามที่จะเปลี่ยนประเภทของเขตข้อมูลจากภายในเปลือก Mongo
ฉันกำลังทำสิ่งนี้ ...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
แต่มันไม่ทำงาน!
คำตอบ:
วิธีเดียวที่จะเปลี่ยน $type
ข้อมูลคือทำการอัปเดตข้อมูลที่มีข้อมูลประเภทที่ถูกต้อง
ในกรณีนี้ดูเหมือนว่าคุณกำลังพยายามที่จะเปลี่ยน$type
จาก 1 (คู่) 2 (สตริง)
ดังนั้นเพียงแค่โหลดเอกสารจากฐานข้อมูลทำการ cast ( new String(x)
) จากนั้นบันทึกเอกสารอีกครั้ง
หากคุณต้องการทำสิ่งนี้โดยทางโปรแกรมและทั้งหมดจากเชลล์คุณสามารถใช้find(...).forEach(function(x) {})
ไวยากรณ์ได้
เพื่อตอบสนองต่อความคิดเห็นที่สองด้านล่าง เปลี่ยนสนามจากหมายเลขที่จะสตริงในคอลเลกชัน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 ดัชนีรายการx.bad
ค่า Variant ที่""+x.bad
Simone อธิบายไว้ทำงานได้ตามต้องการสร้างค่า String แทน 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); } );
สำหรับการแปลงสตริงเป็น int
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()
db.coll.find().forEach(function(data) {
db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
เริ่มต้น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"
เป็นสตริงเมื่อค่าของมันเป็นสองเท่านี่จึงจับคู่องค์ประกอบที่"a"
เป็นประเภท1
(double)ส่วนที่สอง[{ $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 บางเวอร์ชันซ้ำกับองค์ประกอบคอลเลกชันทั้งหมดที่ฝั่งไคลเอ็นต์
อย่างไรก็ตามคุณสามารถใช้การประมวลผลฝั่งเซิร์ฟเวอร์ของ MongoDB โดยใช้ขั้นตอนการสรุปรวมและขั้นตอนการ $ outเป็น:
$ out stage จะแทนที่คอลเล็กชันที่มีอยู่ด้วยการรวบรวมผลลัพธ์ใหม่
ตัวอย่าง:
db.documents.aggregate([
{
$project: {
_id: 1,
numberField: { $substr: ['$numberField', 0, -1] },
otherField: 1,
differentField: 1,
anotherfield: 1,
needolistAllFieldsHere: 1
},
},
{
$out: 'documents',
},
]);
ในการแปลงเขตข้อมูลของชนิดสตริงเป็นเขตข้อมูลวันที่คุณจะต้องวนซ้ำเคอร์เซอร์ที่ส่งคืนโดยfind()
วิธีการใช้forEach()
วิธีการภายในวงวนแปลงเขตข้อมูลเป็นวัตถุวันที่แล้วอัปเดตเขตข้อมูลโดยใช้ตัว$set
ดำเนินการ
ใช้ประโยชน์จากการใช้APIจำนวนมากสำหรับการอัปเดตจำนวนมากซึ่งให้ประสิทธิภาพที่ดีกว่าเนื่องจากคุณจะส่งการดำเนินการไปยังเซิร์ฟเวอร์ด้วยจำนวน 1,000 รายการซึ่งให้ประสิทธิภาพที่ดีกว่าเนื่องจากคุณไม่ได้ส่งคำขอไปยังเซิร์ฟเวอร์เพียงครั้งเดียว 1,000 คำขอ
ต่อไปนี้จะแสดงให้เห็นถึงวิธีการนี้ตัวอย่างแรกใช้ API >= 2.6 and < 3.2
เป็นกลุ่มที่มีอยู่ในรุ่น มันอัพเดตเอกสารทั้งหมดในคอลเลกชันโดยการเปลี่ยน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
ซึ่งได้คัดค้าน API จำนวนมากและให้ชุด apis ใหม่ที่ใช้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 });
ในการแปลง int32 เป็นสตริงใน mongo โดยไม่ต้องสร้างอาร์เรย์เพียงเพิ่ม "" ไปยังหมายเลขของคุณ :-)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
สิ่งที่ช่วยให้ฉันเปลี่ยนประเภทของวัตถุใน MondoDB เป็นเพียงบรรทัดง่าย ๆ ที่กล่าวถึงก่อนหน้านี้ ... :
db.Users.find({age: {$exists: true}}).forEach(function(obj) {
obj.age = new NumberInt(obj.age);
db.Users.save(obj);
});
ผู้ใช้คือคอลเล็กชันของฉันและอายุเป็นวัตถุที่มีสตริงแทนจำนวนเต็ม (int32)
ฉันต้องการเปลี่ยนประเภทข้อมูลของเขตข้อมูลหลายแห่งในคอลเลกชันดังนั้นฉันจึงใช้สิ่งต่อไปนี้เพื่อทำการเปลี่ยนแปลงประเภทข้อมูลหลายชุดในการรวบรวมเอกสาร ตอบคำถามเก่า แต่อาจมีประโยชน์สำหรับผู้อื่น
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);
});
ประเภทการเปลี่ยนแปลงการสาธิตของฟิลด์กลางจากสตริงไปยัง 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 เป็นเพียงตัวอย่างของสไตล์เช่น
ตัวเลข, สตริง, บูลีนที่หวังว่าคำตอบจะช่วยคนอื่น
ฉันใช้สคริปต์นี้ในคอนโซล 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
ข้อมูลของเอกสารบางอย่างที่นี่เป็นโปรแกรมเล็ก ๆ ที่ฉันได้ทำ