Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:
object o = null;
DateTime d = (DateTime)o;
Он выкинет NullReferenceException
в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.
Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:
" />
Здесь SelectedDate
на самом деле является свойством - типа DateTime
- типа Calendar
Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException
, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...
Единственный способ изменить $type
данных - выполнить обновление данных, в которых данные имеют правильный тип.
В этом случае похоже, что вы пытаетесь измените значение $type
с 1 (double) на 2 (строка) .
Так просто загрузите документ из БД, выполните трансляцию (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);
});
Мне нужно изменить тип данных нескольких полей в коллекции, поэтому я использовал следующее, чтобы сделать несколько изменений типа данных в коллекции документов. Ответьте на старый вопрос, но может быть полезным для других.
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);
});
Чтобы преобразовать поле типа string в поле даты, вам потребуется повторить курсор, возвращаемый методом find()
, с использованием метода forEach()
, в пределах цикл преобразует поле в объект Date, а затем обновляет поле с помощью оператора $set
.
Воспользуйтесь преимуществами Bulk API для массовые обновления, которые обеспечивают лучшую производительность, поскольку вы будете отправлять операции на сервер пакетами 1000, что дает вам лучшую производительность, поскольку вы не отправляете каждый запрос на сервер всего один раз в каждые 1000 запросов.
Ниже показан этот подход, в первом примере используется Bulk API, доступный в версиях MongoDB >= 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
, которая с тех пор устарела Bulk 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 });
Преобразование строк в 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);
Для float:
obj.my_value= parseFloat(obj.my_value);
Что действительно помогло мне изменить тип объекта в MondoDB, была просто эта простая строка, возможно, упомянутая здесь ...:
db.Users.find({age: {$exists: true}}).forEach(function(obj) {
obj.age = new NumberInt(obj.age);
db.Users.save(obj);
});
Пользователи - моя коллекция, а возраст - это объект, который имела строку вместо целого числа (int32).
Чтобы преобразовать int32 в строку в mongo без создания массива, просто добавьте «» к вашему номеру: -)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
demo change type of field mid from string to mongo objectId using 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 - еще один пример таких стилей, как
Число, строка, логическое значение, которое надеется ответ поможет кому-то другому.
db.coll.find().forEach(function(data) {
db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
Я использую этот скрипт в консоли 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)
);
}
Преобразование строкового поля в Integer:
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);
});