Я пытаюсь изменить тип поля изнутри оболочки Монго.
Я делаю это...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Но это не работает!
Я пытаюсь изменить тип поля изнутри оболочки Монго.
Я делаю это...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Но это не работает!
Единственный способ изменить $type
данных $type
- это выполнить обновление данных, в которых данные имеют правильный тип.
В этом случае похоже, что вы пытаетесь изменить $type
от 1 (double) до 2 (string).
Поэтому просто загрузите документ из БД, выполните трансляцию (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);
});
Преобразовать строковое поле в 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);
});
Преобразование строк в 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);
db.coll.find().forEach(function(data) {
db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
Чтобы преобразовать int32 в строку в mongo без создания массива просто добавьте "" к вашему номеру: -)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
все ответы до сих пор используют некоторую версию forEach, повторяя все элементы коллекции на стороне клиента.
Однако вы можете использовать серверную обработку MongoDB, используя агрегатный конвейер и этап $ out как:
этап $ out атомарно заменяет существующую коллекцию новой коллекцией результатов.
пример:
db.documents.aggregate([
{
$project: {
_id: 1,
numberField: { $substr: ['$numberField', 0, -1] },
otherField: 1,
differentField: 1,
anotherfield: 1,
needolistAllFieldsHere: 1
},
},
{
$out: 'documents',
},
]);
Чтобы преобразовать поле типа 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
, которая с тех пор не одобрила Массовый 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 });
Что действительно помогло мне изменить тип объекта в 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);
});
Я использую этот script в консоли mongodb для преобразования строк в float...
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)
);
}
demo change type of field mid from string to mongo objectИспользуя мангустку
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 - еще один пример таких стилей, как
Number, string, boolean, которые надеются, что ответ поможет кому-то другому.
в моем случае я использую следующие
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}});
});
}
Начиная с 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)). Вторая часть [{ $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
можно найти в этой таблице.