sql >> Base de Datos >  >> NoSQL >> MongoDB

Convertir algunos campos en Mongo de String a Array

No podemos usar el $type operador para filtrar nuestros documentos aquí porque el tipo de los elementos en nuestra matriz es "cadena" y como se menciona en la documentación:

Pero, afortunadamente, MongoDB también proporciona el $exists operador que se puede utilizar aquí con un índice de matriz numérica.

Ahora, ¿cómo podemos actualizar esos documentos?

Bueno, desde MongoDB versión <=3.2, la única opción que tenemos es mapReduce() pero primero veamos la otra alternativa en el próximo lanzamiento de MongoDB.

A partir de MongoDB 3.4, podemos $project nuestros documentos y usar el $split operador para dividir nuestra cadena en una matriz de subcadenas.

Tenga en cuenta que para dividir solo aquellas "etiquetas" que son cadenas, necesitamos un lógico $cond procesamiento de ition para dividir solo los valores que son cadenas. La condición aquí es $eq que se evalúan como true cuando el $type del campo es igual a "string" . Por cierto $type aquí hay algo nuevo en 3.4.

Finalmente, podemos sobrescribir la colección anterior usando $out operador de etapa de tubería. Pero necesitamos especificar explícitamente la inclusión de otro campo en el $project escenario .

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

Con mapReduce , necesitamos usar el Array.prototype.split() para emitir la matriz de subcadenas en nuestra función de mapa . También necesitamos filtrar nuestros documentos usando la opción "consultar". A partir de ahí, necesitaremos iterar la matriz de "resultados" y $set el nuevo valor para "etiquetas" usando operaciones masivas usando el bulkWrite() método nuevo en 3.2 o el ahora obsoleto Bulk() si estamos en 2.6 o 3.0 como se muestra aquí.

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