Я намагаюся змінити тип поля з оболонки монго.
Я роблю це ...
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
з 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-index-item x.bad
. Варіант ""+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);
});
Перетворити поле Integer в String:
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()
Починаючи 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 атомно замінює існуючу колекцію новою колекцією результатів.
приклад:
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
оператора.
Скористайтеся перевагою використання групового API для масових оновлень, які пропонують кращу продуктивність, оскільки ви будете відправляти операції на сервер партіями, наприклад, 1000, що дає вам кращу ефективність, оскільки ви не надсилаєте кожен запит на сервер, а раз у раз 1000 запитів.
Далі демонструється такий підхід, перший приклад використовує груповий 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 });
Щоб конвертувати int32 в рядок у монго, не створюючи масив, просто додайте "" до свого номера :-)
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
якогось документа, ось невеличка програма, яку я зробив / використав .