Une chance d'un exemple - changer un type de champ de int en chaîne (ou vice versa), à partir du shell?
Alister Bulman
30
dans le cas où Int32-> String, new String(x.bad)crée une collection de chaînes avec une x.badvaleur d' élément d'index 0 . Variante ""+x.bad, décrite par Simone, fonctionne comme vous le souhaitez - crée une valeur de chaîne au lieu de Int32
Dao
Le code ci-dessus convertit les données de champ de double en tableau au lieu de double en chaîne. Mes données réelles étaient dans ce format: 3.1 alors que le code simone fonctionne bien pour moi
Pankaj Khurana
2
Il y avait une situation où j'avais besoin de convertir le champ _id et de ne pas entrer en conflit avec d'autres index:db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
Matt Molnar
@SundarBons oui vous réécrivez un champ dans votre base de données, c'est un gros problème, peu importe comment vous le faites. Si vous utilisiez SQL et que c'était une grande table, vous devrez probablement prendre un certain temps d'arrêt.
C'est génial - savez-vous comment convertir une chaîne (pensez à une devise comme «1.23») en entier 123? Je suppose que vous devrez l'analyser sous forme de virgule flottante ou décimale, de le multiplier par 100, puis de l'enregistrer en tant qu'entier, mais je ne trouve pas les bons documents pour le faire. Merci!
Brian Armstrong
En fait, ce travail est bon. Mais j'ai une application fonctionnant avec mongoid 2.4.0-stable qui a des champs tels que field: customer_count, type: Integer & une validation comme validates_numericality_of: customer_count qui fonctionnait bien. Maintenant, lorsque je passe à mongoid vers 3.0.16, lorsque j'attribue une valeur de chaîne, il la convertit automatiquement en 0. sans erreur. Je veux lancer une erreur sur une mauvaise affectation de données, ce comportement me semble étrange.
Swapnil Chincholkar
4
J'ai couru ceci et j'ai eu l'erreur: Erreur: impossible de convertir la chaîne en entier (shell): 1
Mittenchops
Et si vous avez besoin de convertir une chaîne (ou un entier 32 bits "normal") en entier 64 bits, utilisez NumberLongcomme ici:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
boryn
ça marche bien. Puis-je savoir comment changer le type de données dans les champs de document incorporés
Au départ Mongo 4.2, db.collection.update()peut accepter un pipeline d'agrégation, permettant enfin la mise à jour d'un champ en fonction de sa propre valeur:
La première partie { a : { $type: 1 } }est la requête de correspondance:
Il filtre les documents à mettre à jour.
Dans ce cas, puisque nous voulons convertir "a"en chaîne lorsque sa valeur est un double, cela correspond aux éléments pour lesquels "a"est de type 1(double)).
Ce tableau fournit les codes représentant les différents types possibles.
La deuxième partie [{ $set: { a: { $toString: "$a" } } }]est le pipeline d'agrégation de mise à jour:
Notez les crochets carrés indiquant que cette requête de mise à jour utilise un pipeline d'agrégation.
$setest un nouvel opérateur d'agrégation ( Mongo 4.2) qui dans ce cas modifie un champ.
Cela peut être simplement lu comme "$set"la valeur de "a"à "$a"converti "$toString".
Ce qui est vraiment nouveau ici, c'est de pouvoir Mongo 4.2référencer le document lui-même lors de sa mise à jour: la nouvelle valeur de "a"est basée sur la valeur existante de "$a".
Notez également "$toString"quel est un nouvel opérateur d'agrégation introduit dans Mongo 4.0.
N'oubliez pas { multi: true }, sinon seul le premier document correspondant sera mis à jour.
Dans le cas où votre casting est pas de deux à chaîne, vous avez le choix entre les différents opérateurs de conversion introduits dans Mongo 4.0tels que $toBool, $toInt...
Et s'il n'y a pas de convertisseur dédié pour votre type ciblé, vous pouvez le remplacer { $toString: "$a" }par une $convertopération: { $convert: { input: "$a", to: 2 } }où la valeur de tose trouve dans ce tableau :
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" } } }] )- le multi : truepeut être évité en utilisantupdateMany
Vasim
1
À partir de 2020, l'utilisation de $ convert devrait être la bonne méthode pour cela, car elle devrait être beaucoup plus efficace (et plus facile à utiliser pour démarrer).
KhalilRavanna
10
toutes les réponses jusqu'à présent utilisent une version de forEach, itérant sur tous les éléments de la collection côté client.
Cependant, vous pouvez utiliser le traitement côté serveur de MongoDB en utilisant un pipeline agrégé et une étape $ out comme:
l'étape $ out remplace de manière atomique la collection existante par la nouvelle collection de résultats.
Je ne sais pas pourquoi ce n'est pas plus voté. Les opérations ligne par ligne sur de grands ensembles de données sont un meurtre sur les performances
Alf47
7
Pour convertir un champ de type chaîne en champ de date, vous devez itérer le curseur renvoyé par la find()méthode à l'aide de la forEach()méthode, dans la boucle, convertir le champ en objet Date, puis mettre à jour le champ à l'aide de l' $setopérateur.
Profitez de l'utilisation de l' API en masse pour les mises à jour en masse qui offrent de meilleures performances car vous enverrez les opérations au serveur par lots de, disons 1000, ce qui vous donne de meilleures performances car vous n'envoyez pas toutes les demandes au serveur, une seule fois dans chaque 1000 demandes.
Ce qui suit illustre cette approche, le premier exemple utilise l'API Bulk disponible dans les versions MongoDB >= 2.6 and < 3.2. Il met à jour tous les documents de la collection en modifiant tous lescreated_at champs en champs de date:
var bulk = db.collection.initializeUnorderedBulkOp(),
counter =0;
db.collection.find({"created_at":{"$exists":true,"$type":2}}).forEach(function(doc){var newDate =newDate(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 queueif(counter %1000!=0){ bulk.execute();}
L'exemple suivant s'applique à la nouvelle version de MongoDB 3.2qui a depuis déconseillé l'API Bulk et fourni un ensemble plus récent d' API en utilisant bulkWrite():
J'ai besoin de changer le type de données de plusieurs champs de la collection, j'ai donc utilisé ce qui suit pour apporter plusieurs changements de type de données dans la collection de documents. Répondez à une vieille question mais peut être utile pour les autres.
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 =newNumberInt(obj.field-name);//string to integer}if(obj.hasOwnProperty('cdate')){
obj.cdate =newISODate(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.
toString
un champ de document, voici le petit programme que j'ai créé / utilisé .Réponses:
La seule façon de modifier le
$type
des données est d'effectuer une mise à jour sur les données où les données ont le type correct.Dans ce cas, il semble que vous essayez de changer le
$type
de 1 (double) à 2 (chaîne) .Chargez simplement le document à partir de la base de données, effectuez le cast (
new String(x)
), puis enregistrez à nouveau le document.Si vous devez le faire par programme et entièrement à partir du shell, vous pouvez utiliser la
find(...).forEach(function(x) {})
syntaxe.En réponse au deuxième commentaire ci-dessous. Remplacez le champ
bad
par un nombre par une chaîne dans la collectionfoo
.la source
new String(x.bad)
crée une collection de chaînes avec unex.bad
valeur d' élément d'index 0 . Variante""+x.bad
, décrite par Simone, fonctionne comme vous le souhaitez - crée une valeur de chaîne au lieu de Int32db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
Convertir le champ String en Integer:
Convertir le champ entier en chaîne:
la source
NumberLong
comme ici:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
Pour la conversion de chaîne en int.
Pour la conversion de chaîne en double.
Pour le flotteur:
la source
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…new NumberInt()
la source
Au départ
Mongo 4.2
,db.collection.update()
peut accepter un pipeline d'agrégation, permettant enfin la mise à jour d'un champ en fonction de sa propre valeur:La première partie
{ a : { $type: 1 } }
est la requête de correspondance:"a"
en chaîne lorsque sa valeur est un double, cela correspond aux éléments pour lesquels"a"
est de type1
(double)).La deuxième partie
[{ $set: { a: { $toString: "$a" } } }]
est le pipeline d'agrégation de mise à jour:$set
est un nouvel opérateur d'agrégation (Mongo 4.2
) qui dans ce cas modifie un champ."$set"
la valeur de"a"
à"$a"
converti"$toString"
.Mongo 4.2
référencer le document lui-même lors de sa mise à jour: la nouvelle valeur de"a"
est basée sur la valeur existante de"$a"
."$toString"
quel est un nouvel opérateur d'agrégation introduit dansMongo 4.0
.N'oubliez pas
{ multi: true }
, sinon seul le premier document correspondant sera mis à jour.Dans le cas où votre casting est pas de deux à chaîne, vous avez le choix entre les différents opérateurs de conversion introduits dans
Mongo 4.0
tels que$toBool
,$toInt
...Et s'il n'y a pas de convertisseur dédié pour votre type ciblé, vous pouvez le remplacer
{ $toString: "$a" }
par une$convert
opération:{ $convert: { input: "$a", to: 2 } }
où la valeur deto
se trouve dans ce tableau :la source
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )
- lemulti : true
peut être évité en utilisantupdateMany
toutes les réponses jusqu'à présent utilisent une version de forEach, itérant sur tous les éléments de la collection côté client.
Cependant, vous pouvez utiliser le traitement côté serveur de MongoDB en utilisant un pipeline agrégé et une étape $ out comme:
exemple:
la source
Pour convertir un champ de type chaîne en champ de date, vous devez itérer le curseur renvoyé par la
find()
méthode à l'aide de laforEach()
méthode, dans la boucle, convertir le champ en objet Date, puis mettre à jour le champ à l'aide de l'$set
opérateur.Profitez de l'utilisation de l' API en masse pour les mises à jour en masse qui offrent de meilleures performances car vous enverrez les opérations au serveur par lots de, disons 1000, ce qui vous donne de meilleures performances car vous n'envoyez pas toutes les demandes au serveur, une seule fois dans chaque 1000 demandes.
Ce qui suit illustre cette approche, le premier exemple utilise l'API Bulk disponible dans les versions MongoDB
>= 2.6 and < 3.2
. Il met à jour tous les documents de la collection en modifiant tous lescreated_at
champs en champs de date:L'exemple suivant s'applique à la nouvelle version de MongoDB
3.2
qui a depuis déconseillé l'API Bulk et fourni un ensemble plus récent d' API en utilisantbulkWrite()
:la source
Pour convertir int32 en chaîne dans mongo sans créer de tableau, ajoutez simplement "" à votre nombre :-)
la source
Ce qui m'a vraiment aidé à changer le type de l'objet dans MondoDB était juste cette simple ligne, peut-être mentionnée auparavant ici ...:
Les utilisateurs sont ma collection et l'âge est l'objet qui avait une chaîne au lieu d'un entier (int32).
la source
J'ai besoin de changer le type de données de plusieurs champs de la collection, j'ai donc utilisé ce qui suit pour apporter plusieurs changements de type de données dans la collection de documents. Répondez à une vieille question mais peut être utile pour les autres.
la source
Essayez cette requête.
la source
demo change le type de champ mid de string à mongo objectId en utilisant mongoose
Mongo ObjectId est juste un autre exemple de styles tels que
Nombre, chaîne, booléen qui espère que la réponse aidera quelqu'un d'autre.
la source
J'utilise ce script dans la console mongodb pour les conversions de chaîne à flotteur ...
Et celui-ci en php)))
la source
dans mon cas, j'utilise suivant
la source