Tôi đang cố gắng thay đổi loại trường từ trong vỏ mongo.
Tôi đang làm việc này...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Nhưng nó không hoạt động!
Tôi đang cố gắng thay đổi loại trường từ trong vỏ mongo.
Tôi đang làm việc này...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Nhưng nó không hoạt động!
Câu trả lời:
Cách duy nhất để thay đổi $type
dữ liệu là thực hiện cập nhật dữ liệu trong đó dữ liệu có đúng loại.
Trong trường hợp này, có vẻ như bạn đang cố gắng thay đổi $type
từ 1 (gấp đôi) thành 2 (chuỗi) .
Vì vậy, chỉ cần tải tài liệu từ DB, thực hiện cast ( new String(x)
) và sau đó lưu tài liệu lại.
Nếu bạn cần thực hiện việc này theo chương trình và hoàn toàn từ shell, bạn có thể sử dụng find(...).forEach(function(x) {})
cú pháp.
Đáp lại bình luận thứ hai dưới đây. Thay đổi trường bad
từ một số thành một chuỗi trong bộ sưu tập 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)
tạo bộ sưu tập Chuỗi có x.bad
giá trị 0-index-item . Biến thể ""+x.bad
, được mô tả bởi Simone hoạt động như mong muốn - tạo giá trị Chuỗi thay vì 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); });
Chuyển đổi trường Chuỗi thành Số nguyên:
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = new NumberInt(obj.field-name);
db.db-name.save(obj);
});
Chuyển đổi trường Integer thành String:
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = "" + obj.field-name;
db.db-name.save(obj);
});
NumberLong
như sau:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
Đối với chuỗi chuyển đổi int.
db.my_collection.find().forEach( function(obj) {
obj.my_value= new NumberInt(obj.my_value);
db.my_collection.save(obj);
});
Đối với chuỗi chuyển đổi gấp đôi.
obj.my_value= parseInt(obj.my_value, 10);
Đối với phao:
obj.my_value= parseFloat(obj.my_value);
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ chủ
new NumberInt()
Bắt đầu Mongo 4.2
,db.collection.update()
có thể chấp nhận một đường ống tổng hợp, cuối cùng cho phép cập nhật trường dựa trên giá trị của chính nó:
// { 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" }
Phần đầu tiên { a : { $type: 1 } }
là truy vấn khớp:
"a"
thành chuỗi khi giá trị của nó là gấp đôi, nên điều này khớp với các phần tử có "a"
kiểu1
(double)).Phần thứ hai [{ $set: { a: { $toString: "$a" } } }]
là đường ống tổng hợp cập nhật:
$set
là một toán tử tổng hợp mới (Mongo 4.2
) trong trường hợp này sửa đổi một trường."$set"
giá trị của "a"
để "$a"
chuyển đổi "$toString"
.Mongo 4.2
tham chiếu chính tài liệu khi cập nhật nó: giá trị mới "a"
dựa trên giá trị hiện có của"$a"
."$toString"
đó là một toán tử tổng hợp mới được giới thiệu trong Mongo 4.0
.Đừng quên { multi: true }
, nếu không thì chỉ có tài liệu phù hợp đầu tiên sẽ được cập nhật.
Trong trường hợp diễn viên của bạn không từ gấp đôi thành chuỗi, bạn có quyền lựa chọn giữa các toán tử chuyển đổi khác nhau được giới thiệu Mongo 4.0
như $toBool
,$toInt
, ...
Và nếu không có bộ chuyển đổi chuyên dụng cho loại mục tiêu của bạn, bạn có thể thay thế { $toString: "$a" }
bằng một $convert
thao tác: { $convert: { input: "$a", to: 2 } }
nơi to
có thể tìm thấy giá trị trong bảng này :
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
có thể tránh sử dụngupdateMany
tất cả các câu trả lời cho đến nay đều sử dụng một số phiên bản forEach, lặp đi lặp lại trên tất cả các phần tử bộ sưu tập phía máy khách.
Tuy nhiên, bạn có thể sử dụng xử lý phía máy chủ của MongoDB bằng cách sử dụng đường ống tổng hợp và giai đoạn $ out như:
giai đoạn $ out về cơ bản thay thế bộ sưu tập hiện có bằng bộ sưu tập kết quả mới.
thí dụ:
db.documents.aggregate([
{
$project: {
_id: 1,
numberField: { $substr: ['$numberField', 0, -1] },
otherField: 1,
differentField: 1,
anotherfield: 1,
needolistAllFieldsHere: 1
},
},
{
$out: 'documents',
},
]);
Để chuyển đổi trường kiểu chuỗi thành trường ngày, bạn sẽ cần lặp lại con trỏ được trả về bởi find()
phương thức bằng forEach()
phương thức, trong vòng lặp chuyển đổi trường thành đối tượng Ngày và sau đó cập nhật trường bằng cách sử dụng$set
toán tử.
Tận dụng lợi thế của việc sử dụng API hàng loạt cho các bản cập nhật hàng loạt mang lại hiệu suất tốt hơn vì bạn sẽ gửi các hoạt động đến máy chủ theo đợt 1000, mang lại cho bạn hiệu suất tốt hơn khi bạn không gửi mọi yêu cầu đến máy chủ, chỉ một lần trong mỗi 1000 yêu cầu.
Sau đây minh họa cách tiếp cận này, ví dụ đầu tiên sử dụng API số lượng lớn có sẵn trong các phiên bản MongoDB >= 2.6 and < 3.2
. Nó cập nhật tất cả các tài liệu trong bộ sưu tập bằng cách thay đổi tất cả các created_at
trường thành các trường ngày:
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(); }
Ví dụ tiếp theo áp dụng cho phiên bản MongoDB mới 3.2
, từ đó đã loại bỏ API hàng loạt và cung cấp một bộ apis mới hơn bằng cách sử dụng 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 });
Để chuyển đổi int32 thành chuỗi trong mongo mà không cần tạo một mảng, chỉ cần thêm "" vào số của bạn :-)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
Điều thực sự giúp tôi thay đổi loại đối tượng trong MondoDB chỉ là dòng đơn giản này, có lẽ được đề cập trước đây ...:
db.Users.find({age: {$exists: true}}).forEach(function(obj) {
obj.age = new NumberInt(obj.age);
db.Users.save(obj);
});
Người dùng là bộ sưu tập của tôi và tuổi là đối tượng có chuỗi thay vì số nguyên (int32).
Tôi cần thay đổi kiểu dữ liệu của nhiều trường trong bộ sưu tập, vì vậy tôi đã sử dụng cách sau để thực hiện nhiều thay đổi loại dữ liệu trong bộ sưu tập tài liệu. Trả lời một câu hỏi cũ nhưng có thể hữu ích cho những người khác.
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.
Hãy thử truy vấn này ..
db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});
bản demo thay đổi loại trường giữa từ chuỗi sang mongo objectId bằng cách sử dụng mongoose
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 chỉ là một ví dụ khác về các phong cách như
Số, chuỗi, boolean hy vọng câu trả lời sẽ giúp người khác.
Tôi sử dụng tập lệnh này trong bảng điều khiển mongodb cho chuỗi để chuyển đổi ...
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); } );
Và cái này bằng 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)
);
}
trong trường hợp của tôi, tôi sử dụng sau
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
một số lĩnh vực tài liệu, đây là chương trình nhỏ tôi đã thực hiện / sử dụng .