Fak*_*ish 5 javascript regex mongodb mongodb-query aggregation-framework
假设我们有一组原始数据:
{ "person": "David, age 102"}
{ "person": "Max, age 8" }
Run Code Online (Sandbox Code Playgroud)
我们希望将该集合转换为:
{ "age": 102 }
{ "age": 8 }
Run Code Online (Sandbox Code Playgroud)
仅使用mongo(d)引擎。(如果所有人的姓名或年龄都相等,则$ substr可以胜任该工作),这可能吗?
假设正则表达式是琐碎的/ \ d + /
这个版本mongod提供了$split运算符,当然可以分割字符串,如下所示。
然后,我们使用变量运算符将新计算的值分配给变量$let。然后可以在in表达式中使用新值来返回“name”和“age”值,使用$arrayElemAt运算符返回指定索引处的元素;0对于第一个元素和-1最后一个元素。
请注意,在in表达式中,我们需要拆分最后一个元素才能返回整数字符串。
最后,我们需要迭代该对象,并使用orCursor将整数字符串转换为数字,并使用批量操作和方法将这些字段的值转换为最大效率。NumberparseIntbulkWrite()$set
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);
}
Run Code Online (Sandbox Code Playgroud)
MongoDB 3.2 弃用了旧的Bulk()API 及其相关方法,并提供了bulkWrite()方法,但不提供$split运算符,因此我们这里唯一的选择是使用该mapReduce()方法来转换数据,然后使用批量操作更新集合。
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);
}
Run Code Online (Sandbox Code Playgroud)
我们需要使用现已弃用的Bulk API。
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();
}
Run Code Online (Sandbox Code Playgroud)