MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Conversion de certains champs dans Mongo de String en Array

Nous ne pouvons pas utiliser le $type opérateur pour filtrer nos documents ici car le type des éléments de notre tableau est "string" et comme mentionné dans la documentation :

Mais heureusement, MongoDB fournit également le $exists opérateur qui peut être utilisé ici avec un index de tableau numérique.

Maintenant, comment pouvons-nous mettre à jour ces documents ?

Eh bien, à partir de la version MongoDB <=3.2, la seule option que nous avons est mapReduce() mais voyons d'abord l'autre alternative dans la prochaine version de MongoDB.

À partir de MongoDB 3.4, nous pouvons $project nos documents et utiliser le $split opérateur pour diviser notre chaîne en un tableau de sous-chaînes.

Notez que pour diviser uniquement les "balises" qui sont des chaînes, nous avons besoin d'un logique $cond traitement d'édition pour diviser uniquement les valeurs qui sont des chaînes. La condition ici est $eq qui évalue à true lorsque le $type du champ est égal à "string" . Au fait $type voici une nouveauté en 3.4.

Enfin, nous pouvons écraser l'ancienne collection en utilisant le $out opérateur d'étape de pipeline. Mais nous devons spécifier explicitement l'inclusion d'un autre champ dans le $project scène .

db.collection.aggregate(
     [
        { "$project": { 
            "tags": { 
                "$cond": [ 
                    { "$eq": [ 
                        { "$type": "$tags" }, 
                        "string"
                    ]}, 
                    { "$split": [ "$tags", " " ] }, 
                    "$tags" 
                ] 
            } 
        }},
        { "$out": "collection" }
    ]
)

Avec mapReduce , nous devons utiliser le Array.prototype.split() pour émettre le tableau de sous-chaînes dans notre fonction map . Nous devons également filtrer nos documents en utilisant l'option "requête". À partir de là, nous devrons parcourir le tableau "results" et $set la nouvelle valeur pour "tags" en utilisant des opérations en masse à l'aide du bulkWrite() méthode nouvelle dans 3.2 ou la méthode maintenant obsolète Bulk() si nous sommes sur 2.6 ou 3.0 comme indiqué ici.

db.collection.mapReduce(
    function() { emit(this._id, this.tags.split(" ")); }, 
    function(key, value) {}, 
    { 
        "out": { "inline": 1 }, 
        "query": { 
            "tags.0": { "$exists": false }, 
            "tags": { "$type": 2 }
        }
    }
)['results']