2011-09-13 3 views
14

J'ai un champ dans mongodb qui est une chaîne. {"field": "some text"}, je veux les convertir tous en tableaux. Je sais que je peux simplement faire défiler tous les documents, aller sur le terrain, puis mettre à jour, mais je me demande s'il y a un moyen plus propre.mongodb type modifier en tableau

Merci.

Répondre

3

Vous pouvez le faire dans une fonction Réduire de map/reduce pour conserver tout le traitement en mongodb. Essentiellement, vous utiliseriez map/reduce pour placer les résultats dans une nouvelle collection, puis vous pourriez les copier dans l'ancienne collection (ou supprimer l'ancienne et renommer la nouvelle). Cela a l'avantage de tout garder à l'intérieur de Mongo.

Mise à jour: Une autre option pourrait être pour vous d'utiliser db.eval pour cela. db.eval s'exécute sur le serveur afin que les mises à jour soient effectuées sur le serveur sans trafic/latence.

Je pense que la seule autre option est celle que vous avez décrite - faites-le sur le client en interrogeant et en mettant à jour chacun d'eux.

+0

Pensez-vous que la carte réduire en mongo sera plus rapide? – Harry

+0

Généralement, cela dépend du nombre de documents et de la quantité de données que vous déplacez entre le serveur et le client. S'il y a beaucoup de données se déplaçant entre le serveur/client, alors vous voulez garder le traitement dans MongoDB avec mapReduce ou essayez db.eval (comme je viens de l'ajouter dans une édition ci-dessus). –

+0

merci pour db.eval, toujours heureux d'apprendre quelque chose de nouveau. – Harry

0

mais je me demande s'il y a un moyen plus propre ..

La réponse courte est non.

MongoDB n'a aucune opération ou commande unique pour effectuer un "type de changement".

La méthode la plus rapide consiste à utiliser l'un des pilotes et à effectuer le changement. Vous pouvez utiliser le shell et écrire une boucle for, mais en termes de vitesse brute, les autres pilotes peuvent être plus rapides. Cela dit, la partie la plus lente du processus va charger toutes les données du disque dans la mémoire pour être changée, puis renvoyer ces données sur le disque. Ce serait vrai même avec une commande magique "change type".

3

essayer cette place

est de changer le type d'un champ de chaîne à tableau dans MongoDB

db.jobs.find({ "jobLocationCity" : { $type : 2 } }).forEach(function (x) { 
    x.jobLocationCity = {"Location":x.jobLocationCity}; 
    db.jobs.save(x); 
}); 

voir le lien pour la réponse de type $ possible values

+0

Cette réponse m'a conduit à une solution que je trouve très succincte. Le problème que j'ai eu avec l'exemple fourni ici est que parce qu'un appel à save() est en cours dans la boucle forEach, le curseur est en train de se foirer et la fonction sera appelée plusieurs fois pour le même document. La solution consiste à appeler snapshot() avant le foreach: db.jobs.find (blah) .snapshot(). ForEach() –

10

Nitin Garg ci-dessus presque fonctionne, sauf son exemple convertit d'une chaîne à un hachage, PAS une chaîne à un tableau.

La prise en compte Joel Harris commentaires de la solution appropriée ressemblerait à ceci:

db.jobs.find({ "jobLocationCity" : { $type : 2 } }).snapshot().forEach(function (x) { 
    x.jobLocationCity = [ jobLocationCity ]; 
    db.jobs.save(x); 
}); 

Ou si vous utilisez db.eval:

function f() { 
    db.jobs.find({ "jobLocationCity" : { $type : 2 } }).snapshot().forEach(function (x) { 
     x.jobLocationCity = [ jobLocationCity ]; 
     db.jobs.save(x); 
    }); 
} 
db.eval(f); 
+2

petit correctif: x.jobLocationCity = [x.jobLocationCity]; – Vitamon

+0

Pourquoi "sauvegarder" et pas "mettre à jour"? – nilskp

5

En fait, la trouvaille ({ "jobLocationCity": { $ type: 2}}) ne fonctionnera pas correctement, car si vous exécutez le script de mise à jour la prochaine fois, il traitera à nouveau les éléments ['mystring'] comme type de chaîne.

Vous devez utiliser quelque chose comme ça pour l'empêcher:

db.message_info.find({ "jobLocationCity" : { $type : 2 } } ).snapshot().forEach(
    function (x) { 
    if (!Array.isArray(x.jobLocationCity)){ 
     x.jobLocationCity = [ x.jobLocationCity ]; 
     db.jobs.save(x); 
    } 
    } 
) 

voir http://docs.mongodb.org/manual/reference/operators/