Я пытаюсь изменить тип поля в оболочке Монго.
Я делаю это ...
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 (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);
});
new String(x.bad)
создает коллекцию Strings со значением 0-index-item x.bad
. Вариант ""+x.bad
, описанный Симоной, работает как нужно - создает значение 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()
Начав 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
можно найти в этой таблице :
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 stage как:
этап $ 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
оператора.
Воспользуйтесь преимуществом 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 });
Чтобы преобразовать 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);
});
Пользователи - это моя коллекция, а age - это объект, в котором вместо целого числа была строка (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);
});
Демо изменить тип поля середины от строки до монго 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
поле для какого-либо документа, вот небольшая программа, которую я сделал / использовал .