it-swarm-ru.tech

MongoDB: Как изменить тип поля?

В Stackoverflow уже есть вопрос, очень похожий на мой вопрос…. Дело в том, что ответ на этот вопрос был для драйвера Java, я пытаюсь сделать это в командной консоли.

Я делаю это ...

db.meta.update({'fields.properties.default': { $type : 1 }}, {'fields.properties.default': { $type : 2 }})

Это не работает!

130
J. Quintas

Единственный способ изменить $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);
});
179
Gates VP

Преобразовать строковое поле в целое число:

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);
});
145
Simone

Для преобразования строки в 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);
34
David Dehghan
db.coll.find().forEach(function(data) {
    db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
18
Russell

Чтобы преобразовать int32 в строку в монго без создания массива просто добавьте "" к вашему номеру :-)

db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {   
  x.mynum = x.mynum + ""; // convert int32 to string
  db.foo.save(x);
});
4
Giulio Roggero

Что действительно помогло мне изменить тип объекта в MondoDB, так это простая строка, возможно, упоминавшаяся ранее здесь:

db.Users.find({age: {$exists: true}}).forEach(function(obj) {
    obj.age = new NumberInt(obj.age);
    db.Users.save(obj);
});

Пользователи - это моя коллекция, а age - это объект, в котором вместо целого числа была строка (int32).

3
Felipe

Чтобы преобразовать поле строкового типа в поле даты, вам нужно будет перебрать курсор, возвращенный методом 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 });
2
chridam

все ответы до сих пор используют некоторую версию forEach, перебирая все элементы коллекции на стороне клиента.

Однако вы можете использовать обработку на сервере MongoDB, используя агрегатный конвейер и $ out stage as:

этап $ out атомарно заменяет существующую коллекцию на новая коллекция результатов.

пример:

db.documents.aggregate([
         {
            $project: {
               _id: 1,
               numberField: { $substr: ['$numberField', 0, -1] },
               otherField: 1,
               differentField: 1,
               anotherfield: 1,
               needolistAllFieldsHere: 1
            },
         },
         {
            $out: 'documents',
         },
      ]);
2
user3616725

Мне нужно изменить тип данных нескольких полей в коллекции, поэтому я использовал следующее для внесения нескольких изменений типа данных в коллекцию документов. Ответ на старый вопрос, но может быть полезным для других.

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); 
});
1
Aakash
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);
});
1
Amarendra Kumar

в моем случае я использую следующие

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}});
  });
}
0
Renish Gotecha

Я использую этот скрипт в консоли 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)
    );


}
0
user3469031

демо изменить тип поля середины от строки до монго 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 - это еще один пример таких стилей, как

Число, строка, логическое значение, которые, надеюсь, ответ поможет кому-то еще.

0
Tran Hoang Hiep