在mongo中执行优先级查询

时间:2016-01-12 10:19:49

标签: regex mongodb mapreduce mongodb-query

示例文档:

{"name":"John", "age":35, "address":".....",.....}
  1. join_month = 3的员工优先级为1
  2. 地址包含字符串“Avenue”的员工为优先级2
  3. 地址中包含字符串“Street”的员工为优先级3
  4. 地址包含字符串“Road”的员工为优先级4
  5. 截至目前,我正处于这个阶段:

    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 } }
    ])
    

    我被困在优先领域。我该怎么办?

1 个答案:

答案 0 :(得分:1)

使用聚合框架,您最好"理想情况下"想要在 $regex 管道步骤中的 $cond 逻辑运算符中使用 $project 过滤器,但不幸的是MongoDB尚未支持这一点。 目前已开启 $project filter using $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() { };

然后对测试集合运行mapduce操作并将结果存储在集合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 } }