Jak zmienić typ pola?

Próbuję zmienić typ pola z wnętrza powłoki mongo.

Robię to...
db.meta.update(
  {'fields.properties.default': { $type : 1 }}, 
  {'fields.properties.default': { $type : 2 }}
)
Ale to nie działa!
 169
Author: Xavier Guihot, 2011-02-11

13 answers

Jedynym sposobem na zmianę $type danych jest wykonanie aktualizacji danych, w których dane mają prawidłowy typ.

W tym przypadku, wygląda na to, że próbujesz zmienić $type od 1 (double) do 2 (string) .

Więc po prostu załaduj dokument z bazy danych, wykonaj cast (new String(x)), a następnie zapisz dokument ponownie.

Jeśli chcesz to zrobić programowo i całkowicie z powłoki, możesz użyć składni find(...).forEach(function(x) {}).


W odpowiedzi na drugi komentarz poniżej. Zmień pole bad z liczby na łańcuch w kolekcji foo.

db.foo.find( { 'bad' : { $type : 1 } } ).forEach( function (x) {   
  x.bad = new String(x.bad); // convert field to string
  db.foo.save(x);
});
 219
Author: Gates VP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 08:01:37

Konwertuj pole String na liczbę całkowitą:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) { 
    obj.field-name = new NumberInt(obj.field-name);
    db.db-name.save(obj);
});

Konwertuj pole Integer na String:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
    obj.field-name = "" + obj.field-name;
    db.db-name.save(obj);
});
 168
Author: Simone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 12:47:54

For string to int conversion.

db.my_collection.find().forEach( function(obj) {
    obj.my_value= new NumberInt(obj.my_value);
    db.my_collection.save(obj);
});

For string to double conversion.

    obj.my_value= parseInt(obj.my_value, 10);

Dla float:

    obj.my_value= parseFloat(obj.my_value);
 46
Author: David Dehghan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 12:02:40

Początek Mongo 4.2, db.collection.update() może akceptować potok agregacji, pozwalając wreszcie na aktualizację pola na podstawie jego własnej wartości:

// { 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" }
  • Pierwsza część { a : { $type: 1 } } to Zapytanie o dopasowanie:

    • filtruje, które dokumenty należy zaktualizować.
    • w tym przypadku, ponieważ chcemy przekonwertować {[5] } na string, gdy jego wartość jest Podwójna, pasuje to do elementów, dla których "a" jest typu 1 (double)).
    • ta tabela zawiera kody reprezentujące różne możliwe typy.
  • Druga część [{ $set: { a: { $toString: "$a" } } }] to potok agregacji aktualizacji:

    • zwróć uwagę na kwadratowe nawiasy oznaczające, że to zapytanie aktualizacyjne używa potoku agregacji.
    • $set jest nowym operatorem agregacji (Mongo 4.2), który w tym przypadku modyfikuje pole.
    • można to po prostu odczytać jako "$set" wartość "a" do "$a" przekonwertowana "$toString".
    • to, co naprawdę nowego tutaj, jest możliwość w Mongo 4.2 aby odwołać się do samego dokumentu podczas jego aktualizacji: nowa wartość "a" opiera się na istniejącej wartości "$a".
    • Zobacz też "$toString" który jest nowym operatorem agregacji wprowadzonym w Mongo 4.0.
  • Nie zapomnij { multi: true }, w przeciwnym razie tylko pierwszy pasujący dokument zostanie zaktualizowany.


W przypadku, gdy Twój rzut nie jest od podwójnego do strunowego, masz wybór pomiędzy różnymi operatorami konwersji wprowadzonymi w Mongo 4.0 takimi jako $toBool, $toInt, ...

A jeśli nie ma dedykowanego konwertera dla Twojego docelowego typu, możesz zastąpić { $toString: "$a" } operacją $convert: { $convert: { input: "$a", to: 2 } } gdzie wartość dla to znajduje się w tabeli :

db.collection.update(
  { a : { $type: 1 } },
  [{ $set: { a: { $convert: { input: "$a", to: 2 } } } }],
  { multi: true }
)
 32
Author: Xavier Guihot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-12 20:43:59
db.coll.find().forEach(function(data) {
    db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
 22
Author: Russell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-12 13:01:29

Wszystkie odpowiedzi do tej pory używają jakiejś wersji forEach, iteracji dla wszystkich elementów kolekcji po stronie klienta.

Możesz jednak użyć przetwarzania po stronie serwera MongoDB, używając agregate pipeline i $ out stage jako:

$out stage atomicznie zastępuje istniejącą kolekcję nowa kolekcja wyników.

Przykład:

db.documents.aggregate([
         {
            $project: {
               _id: 1,
               numberField: { $substr: ['$numberField', 0, -1] },
               otherField: 1,
               differentField: 1,
               anotherfield: 1,
               needolistAllFieldsHere: 1
            },
         },
         {
            $out: 'documents',
         },
      ]);
 12
Author: user3616725,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-03 12:39:21

Aby przekonwertować pole typu string na pole date, trzeba będzie iterować kursor zwracany przez find() metoda z wykorzystaniem forEach() metoda, w pętli przekonwertuj pole na obiekt daty, a następnie zaktualizuj pole za pomocą $set centrala.

Skorzystaj z korzystania z Bulk API dla masowych aktualizacji, które oferują lepszą wydajność, ponieważ będziesz wysyłać operacje na serwer w partie powiedzmy 1000, co daje lepszą wydajność, ponieważ nie wysyłasz każdego żądania do serwera, tylko raz na każde 1000 żądań.

Poniższy przykład pokazuje to podejście, pierwszy przykład wykorzystuje zbiorcze API dostępne w wersjach MongoDB >= 2.6 and < 3.2. Aktualizuje wszystkie dokumenty w zbiorze zmieniając wszystkie pola created_at na pola daty:

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(); }

Następny przykład dotyczy nowej wersji MongoDB 3.2, która od deprecated the Bulk API i dostarczył nowszy zestaw interfejsów API wykorzystujących 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 });
 7
Author: chridam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-22 11:44:20

Aby przekonwertować int32 na string w mongo bez tworzenia tablicy wystarczy dodać "" do swojej liczby :-)

db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {   
  x.mynum = x.mynum + ""; // convert int32 to string
  db.foo.save(x);
});
 3
Author: Giulio Roggero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-03 14:19:33

To, co naprawdę pomogło mi zmienić typ obiektu w MondoDB, to tylko ta prosta linia, być może wspomniana wcześniej...:

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

Users are my collection and age is the object which had a string zamiast an integer (int32).

 3
Author: Felipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-28 05:46:33

Muszę zmienić typ danych wielu pól w kolekcji, więc użyłem poniższego, aby wprowadzić wiele zmian typu danych w kolekcji dokumentów. Odpowiedź na Stare pytanie, ale może być pomocna dla innych.

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
Author: Aakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 11:49:54
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.

Spróbuj tego zapytania..

db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});
 1
Author: Amarendra Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-25 13:40:52

Demo zmiana typu pola mid z string na Mongo objectId za pomocą 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 to kolejny przykład takich stylów jak

Number, string, boolean, które mają nadzieję, że odpowiedź pomoże komuś innemu.

 1
Author: Tran Hoang Hiep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 00:38:32

Używam tego skryptu w konsoli mongodb do konwersji typu string...

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

I ten w 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
Author: user3469031,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-03 09:25:12