MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Convertendo alguns campos no Mongo de String para Array


Não podemos usar o $type operador para filtrar nossos documentos aqui porque o tipo dos elementos em nosso array é "string" e conforme mencionado na documentação:

Mas felizmente o MongoDB também fornece o $exists operador que pode ser usado aqui com um índice de matriz numérica.

Agora, como podemos atualizar esses documentos?

Bem, da versão MongoDB <=3.2, a única opção que temos é mapReduce() mas primeiro vamos ver a outra alternativa na próxima versão do MongoDB.

A partir do MongoDB 3.4, podemos $project nossos documentos e use o $split operador para dividir nossa string em uma matriz de substrings.

Observe que para dividir apenas as "tags" que são string, precisamos de um lógico $cond processamento de ção para dividir apenas os valores que são string. A condição aqui é $eq que avaliam como true quando o $type do campo é igual a "string" . A propósito $type aqui é novo em 3.4.

Finalmente, podemos substituir a coleção antiga usando o $out operador de estágio de pipeline. Mas precisamos especificar explicitamente a inclusão de outro campo no $project estágio .
db.collection.aggregate(
     [
        { "$project": { 
            "tags": { 
                "$cond": [ 
                    { "$eq": [ 
                        { "$type": "$tags" }, 
                        "string"
                    ]}, 
                    { "$split": [ "$tags", " " ] }, 
                    "$tags" 
                ] 
            } 
        }},
        { "$out": "collection" }
    ]
)

Com mapReduce , precisamos usar a matriz Array.prototype.split() para emitir o array de substrings em nossa função map . Também precisamos filtrar nossos documentos usando a opção "query". A partir daí, precisaremos iterar o array "results" e $set o novo valor para "tags" usando operações em massa usando o bulkWrite() método novo na versão 3.2 ou o agora obsoleto Bulk() se estivermos na versão 2.6 ou 3.0, conforme mostrado aqui.
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']