Ich versuche, den Typ eines Feldes innerhalb der Mongo-Shell zu ändern.
Ich mache das ...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Aber es funktioniert nicht!
Ich versuche, den Typ eines Feldes innerhalb der Mongo-Shell zu ändern.
Ich mache das ...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
Aber es funktioniert nicht!
Antworten:
Die einzige Möglichkeit, $type
die Daten zu ändern, besteht darin, eine Aktualisierung der Daten durchzuführen, bei denen die Daten den richtigen Typ haben.
In diesem Fall scheinen Sie zu versuchen, die Zahl $type
von 1 (doppelt) in 2 (Zeichenfolge) zu ändern .
Laden Sie also einfach das Dokument aus der Datenbank, führen Sie cast ( new String(x)
) aus und speichern Sie das Dokument erneut.
Wenn Sie dies programmgesteuert und vollständig über die Shell ausführen müssen, können Sie die find(...).forEach(function(x) {})
Syntax verwenden.
Als Antwort auf den zweiten Kommentar unten. Ändern Sie das Feld bad
von einer Zahl in eine Zeichenfolge in der Sammlung 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)
eine Sammlung von Strings mit dem x.bad
Wert 0-index-item erstellt . Die ""+x.bad
von Simone beschriebene Variante funktioniert wie gewünscht - erstellt einen String-Wert anstelle von 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); });
String-Feld in Integer konvertieren:
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = new NumberInt(obj.field-name);
db.db-name.save(obj);
});
Ganzzahlfeld in Zeichenfolge konvertieren:
db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
obj.field-name = "" + obj.field-name;
db.db-name.save(obj);
});
NumberLong
wie db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
Für die Konvertierung von Zeichenfolgen in int.
db.my_collection.find().forEach( function(obj) {
obj.my_value= new NumberInt(obj.my_value);
db.my_collection.save(obj);
});
Für die Konvertierung von Zeichenfolgen in doppelte.
obj.my_value= parseInt(obj.my_value, 10);
Für Schwimmer:
obj.my_value= parseFloat(obj.my_value);
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
new NumberInt()
Starten Mongo 4.2
, db.collection.update()
kann eine Aggregation Pipeline akzeptieren, schließlich die Aktualisierung eines Feldes ermöglicht , basierend auf seinen eigenen Wert:
// { 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" }
Der erste Teil { a : { $type: 1 } }
ist die Übereinstimmungsabfrage:
"a"
dies Elementen, für die "a"
der Typ 1
(double) ist , da wir in einen String konvertieren möchten, wenn sein Wert ein Double ist .Der zweite Teil [{ $set: { a: { $toString: "$a" } } }]
ist die Update-Aggregations-Pipeline:
$set
ist ein neuer Aggregationsoperator ( Mongo 4.2
), der in diesem Fall ein Feld ändert."$set"
der Wert der "a"
zu "$a"
umgewandelt "$toString"
.Mongo 4.2
, beim Aktualisieren auf das Dokument selbst zu verweisen: Der neue Wert für "a"
basiert auf dem vorhandenen Wert von "$a"
."$toString"
welcher neue Aggregationsoperator in eingeführt wurde Mongo 4.0
.Vergessen Sie nicht { multi: true }
, sonst wird nur das erste übereinstimmende Dokument aktualisiert.
Falls Ihr Guss nicht doppelt zu bespannen, haben Sie die Wahl zwischen verschiedenen Konvertierungsoperator in eingeführt Mongo 4.0
, wie $toBool
, $toInt
...
Und wenn es für Ihren Zieltyp keinen dedizierten Konverter gibt, können Sie ihn durch { $toString: "$a" }
eine $convert
Operation ersetzen : { $convert: { input: "$a", to: 2 } }
Der Wert für to
befindet sich in dieser Tabelle :
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" } } }] )
- Das multi : true
kann vermieden werden mitupdateMany
Alle bisherigen Antworten verwenden eine Version von forEach, die clientseitig über alle Sammlungselemente iteriert.
Sie können jedoch die serverseitige Verarbeitung von MongoDB verwenden, indem Sie die aggregierte Pipeline und die $ out-Phase wie folgt verwenden :
Die Phase $ out ersetzt atomar die vorhandene Sammlung durch die neue Ergebnissammlung.
Beispiel:
db.documents.aggregate([
{
$project: {
_id: 1,
numberField: { $substr: ['$numberField', 0, -1] },
otherField: 1,
differentField: 1,
anotherfield: 1,
needolistAllFieldsHere: 1
},
},
{
$out: 'documents',
},
]);
Um ein Feld vom Typ Zeichenfolge in ein Datumsfeld zu konvertieren, müssen Sie den von der find()
Methode zurückgegebenen Cursor mithilfe von iterierenforEach()
Methode zurückgegebenen , das Feld innerhalb der Schleife in ein Datumsobjekt konvertieren und das Feld dann mit dem $set
Operator aktualisieren .
Nutzen Sie die Bulk-API für Bulk-Updates, die eine bessere Leistung bieten, da Sie die Vorgänge in Stapeln von beispielsweise 1000 an den Server senden. Dies führt zu einer besseren Leistung, da Sie nicht jede Anforderung nur einmal an den Server senden 1000 Anfragen.
Im Folgenden wird dieser Ansatz veranschaulicht. Im ersten Beispiel wird die in MongoDB-Versionen verfügbare Bulk-API verwendet >= 2.6 and < 3.2
. . Es aktualisiert alle Dokumente in der Sammlung, indem alle created_at
Felder in Datumsfelder geändert werden:
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(); }
Das nächste Beispiel gilt für die neue MongoDB-Version, 3.2
die seitdem die Bulk-API veraltet und einen neueren Satz von APIs bereitgestellt hat, indem sie 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 });
Um int32 in mongo in einen String umzuwandeln, ohne ein Array zu erstellen, fügen Sie einfach "" zu Ihrer Nummer hinzu :-)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
Was mir wirklich geholfen hat, den Typ des Objekts in MondoDB zu ändern, war nur diese einfache Zeile, die hier vielleicht schon erwähnt wurde ...:
db.Users.find({age: {$exists: true}}).forEach(function(obj) {
obj.age = new NumberInt(obj.age);
db.Users.save(obj);
});
Benutzer sind meine Sammlung und Alter ist das Objekt, das eine Zeichenfolge anstelle einer Ganzzahl (int32) hatte.
Ich muss den Datentyp mehrerer Felder in der Sammlung ändern, daher habe ich Folgendes verwendet, um mehrere Datentypänderungen in der Sammlung von Dokumenten vorzunehmen. Beantworten Sie eine alte Frage, aber sie kann für andere hilfreich sein.
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.
Versuchen Sie diese Abfrage ..
db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});
Demo Ändern Sie den Feldtyp in der Mitte von String zu Mongo ObjectId mit Mungo
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 ist nur ein weiteres Beispiel für Stile wie
Zahl, Zeichenfolge, Boolescher Wert, die hoffen, dass die Antwort jemand anderem hilft.
Ich benutze dieses Skript in der Mongodb-Konsole für String-Float-Konvertierungen ...
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); } );
Und dieser in 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)
);
}
In meinem Fall verwende ich Folgendes
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
das Feld eines Dokuments benötigt, ist hier das kleine Programm, das ich erstellt / verwendet habe .