De optimale manier in MongoDB versie 3.4.
Deze versie van mongod
biedt de $split
operator die natuurlijk de string splitst zoals getoond hier
.
Vervolgens wijzen we de nieuw berekende waarde toe aan een variabele met behulp van de $let
variabele operator. De nieuwe waarde kan dan worden gebruikt in de in expressie om de "name" en de "age" waarden te retourneren met behulp van de $arrayElemAt
operator om het element op een gespecificeerde index te retourneren; 0
voor het eerste element en -1
voor het laatste onderdeel.
Merk op dat in de in expressie moeten we het laatste element splitsen om de string van integer te retourneren.
Ten slotte moeten we de Cursor
. herhalen object en cast de string van integer naar numeriek met behulp van Nummer
of parseInt
en gebruik bulkbewerking en de bulkWrite()
methode om $set
de waarde voor dat veld voor maximale efficiëntie.
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 of nieuwer.
MongoDB 3.2 deprecieert de oude Bulk()
API en de bijbehorende methoden
en geeft de bulkWrite()
methode, maar het biedt niet de $split
operator, dus de enige optie die we hier hebben is om de mapReduce()
methode om onze gegevens te transformeren en vervolgens de verzameling bij te werken met behulp van bulkbewerking.
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 versie 2.6 of 3.0.
We moeten de nu verouderde Bulk API gebruiken .
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();
}