示例文档:
{"name":"John", "age":35, "address":".....",.....}
- join_month=3为优先级1的员工
- 地址包含字符串"Avenue"的员工的优先级为2
- 地址包含字符串"街道"的员工的优先级为3
- 地址包含字符串"Road"的员工优先考虑4
到目前为止,我正处于这个阶段:
db.collection.aggregate([
{ "$match": {
"$or": [
{ "join_month": 3 },
{ "address": /.*Avenue.*/i },
{ "address": /.*Street.*/i },
{ "address": /.*Road.*/i }
]
}},
{ "$project": {
"name": 1,
"age": 1,
"_id": 0,
"priority": { ?????????? }
}},
{ "$sort": { "priority": 1 } }
])
我被困在优先领域。我应该在那里放什么?
使用聚合框架,您"理想情况下"希望在$project
管道步骤中的$cond
逻辑运算符中使用$regex
过滤器,但不幸的是MongoDB尚未支持这一点。使用$regex的当前打开的$项目筛选器有一个JIRA票证
但是,一种变通方法(虽然不是性能最佳的解决方案)是使用map-reduce
。考虑填充测试集合:
db.test.insert([
{ _id: 0, "join_month": 12, "address": "33 Point Avenue", "name": "John", "age":35 },
{ _id: 1, "join_month": 10, "address": "2A Broad Street, Surbub", "name": "Jane", "age":21 },
{ _id: 2, "join_month": 3, "address": "127 Umpstreeten Road, Surbub", "name": "Alan", "age":63 },
{ _id: 3, "join_month": 3, "address": "127 Umpstreeten Road, Surbub", "name": "Louise", "age":30 }
])
将地图功能定义为:
var mapper = function() {
var priority;
if (this.join_month==3){
priority = 1;
}
else if (this.address.match(/Avenue/i)){
priority = 2;
}
else if (this.address.match(/Street/i)){
priority = 3;
}
else if (this.address.match(/Road/i)){
priority = 4;
}
else {
priority = 99;
}
var value = {
"name": this.name,
"age": this.age,
"priority": priority
};
emit( this._id, value );
};
reduce函数如下:
var reducer = function() { };
然后对测试集合运行mapuce操作,并将结果存储在集合mr_result
中
db.test.mapReduce(mapper, reducer, {
"out": 'mr_result'
"query": {
"$or": [
{ "join_month": 3 },
{ "address": /.*Avenue.*/i },
{ "address": /.*Street.*/i },
{ "address": /.*Road.*/i }
]
}
})
查询结果集合:
db.mr_result.find().sort({ "priority": 1})
样本输出
{ "_id" : 2, "value" : { "name" : "Alan", "age" : 63, "priority" : 1 } }
{ "_id" : 3, "value" : { "name" : "Louise", "age" : 30, "priority" : 1 } }
{ "_id" : 0, "value" : { "name" : "John", "age" : 35, "priority" : 2 } }
{ "_id" : 1, "value" : { "name" : "Jane", "age" : 21, "priority" : 3 } }