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