MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Conversione di alcuni campi in Mongo da String a Array

Non possiamo utilizzare $type operatore per filtrare i nostri documenti qui perché il tipo degli elementi nel nostro array è "string" e come menzionato nella documentazione:

Ma fortunatamente MongoDB fornisce anche $exists operatore che può essere utilizzato qui con un indice di matrice numerico.

Ora come possiamo aggiornare quei documenti?

Bene, dalla versione MongoDB <=3.2, l'unica opzione che abbiamo è mapReduce() ma prima diamo un'occhiata all'altra alternativa nella prossima versione di MongoDB.

A partire da MongoDB 3.4, possiamo $project i nostri documenti e usa il $split per dividere la nostra stringa in un array di sottostringhe.

Nota che per dividere solo quei "tag" che sono string, abbiamo bisogno di un logico $cond elaborazione ition per dividere solo i valori che sono string. La condizione qui è $eq che restituisce true quando il $type del campo è uguale a "string" . A proposito $type ecco una novità in 3.4.

Infine possiamo sovrascrivere la vecchia raccolta utilizzando $out operatore della fase del gasdotto. Ma dobbiamo specificare esplicitamente l'inclusione di altri campi nel $project fase .

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

Con mapReduce , dobbiamo utilizzare l' Array.prototype.split() per emettere l'array di sottostringhe nella nostra funzione mappa . Abbiamo anche bisogno di filtrare i nostri documenti usando l'opzione "query". Da lì dovremo iterare l'array "results" e $set il nuovo valore per i "tag" utilizzando operazioni in blocco utilizzando bulkWrite() metodo nuovo in 3.2 o l'ormai deprecato Bulk() se siamo su 2.6 o 3.0 come mostrato qui.

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']