La manière optimale dans MongoDB version 3.4.
Cette version de mongod
fournit le $split
opérateur qui, bien sûr, divise la chaîne comme indiqué ici
.
Nous attribuons ensuite la valeur nouvellement calculée à une variable à l'aide du $let
opérateur variable. La nouvelle valeur peut ensuite être utilisée dans le in expression pour renvoyer les valeurs "name" et "age" en utilisant le $arrayElemAt
opérateur pour renvoyer l'élément à un index spécifié ; 0
pour le premier élément et -1
pour le dernier élément.
Notez que dans le dans expression, nous devons diviser le dernier élément afin de renvoyer la chaîne d'entier.
Enfin, nous devons itérer le Cursor
objet et convertir la chaîne d'entier en numérique en utilisant Number
ou parseInt
et utilisez l'opération en bloc et le bulkWrite()
méthode pour $set
la valeur de ces champs pour une efficacité maximale.
let requests = [];
db.coll.aggregate(
[
{ "$project": {
"person": {
"$let": {
"vars": {
"infos": { "$split": [ "$person", "," ] }
},
"in": {
"name": { "$arrayElemAt": [ "$$infos", 0 ] },
"age": {
"$arrayElemAt": [
{ "$split": [
{ "$arrayElemAt": [ "$$infos", -1 ] },
" "
]},
-1
]
}
}
}
}
}}
]
).forEach(document => {
requests.push({
"updateOne": {
"filter": { "_id": document._id },
"update": {
"$set": {
"name": document.person.name,
"age": Number(document.person.age)
},
"$unset": { "person": " " }
}
}
});
if ( requests.length === 500 ) {
// Execute per 500 ops and re-init
db.coll.bulkWrite(requests);
requests = [];
}}
);
// Clean up queues
if(requests.length > 0) {
db.coll.bulkWrite(requests);
}
MongoDB 3.2 ou plus récent.
MongoDB 3.2 déprécie l'ancien Bulk()
API et ses méthodes
et fournit le bulkWrite()
mais elle ne fournit pas le $split
donc la seule option que nous avons ici est d'utiliser le mapReduce()
méthode pour transformer nos données puis mettre à jour la collection en utilisant une opération en masse.
var mapFunction = function() {
var person = {},
infos = this.person.split(/[,\s]+/);
person["name"] = infos[0];
person["age"] = infos[2];
emit(this._id, person);
};
var results = db.coll.mapReduce(
mapFunction,
function(key, val) {},
{ "out": { "inline": 1 } }
)["results"];
results.forEach(document => {
requests.push({
"updateOne": {
"filter": { "_id": document._id },
"update": {
"$set": {
"name": document.value.name,
"age": Number(document.value.age)
},
"$unset": { "person": " " }
}
}
});
if ( requests.length === 500 ) {
// Execute per 500 operations and re-init
db.coll.bulkWrite(requests);
requests = [];
}}
);
// Clean up queues
if(requests.length > 0) {
db.coll.bulkWrite(requests);
}
MongoDB version 2.6 ou 3.0.
Nous devons utiliser l'API Bulk désormais obsolète .
var bulkOp = db.coll.initializeUnorderedBulkOp();
var count = 0;
results.forEach(function(document) {
bulkOp.find({ "_id": document._id}).updateOne(
{
"$set": {
"name": document.value.name,
"age": Number(document.value.age)
},
"$unset": { "person": " " }
}
);
count++;
if (count === 500 ) {
// Execute per 500 operations and re-init
bulkOp.execute();
bulkOp = db.coll.initializeUnorderedBulkOp();
}
});
// clean up queues
if (count > 0 ) {
bulkOp.execute();
}