performing priority query in mongo

微笑、不失礼 提交于 2019-12-11 00:39:11

问题


sample document :

{"name":"John", "age":35, "address":".....",.....}
  1. Employees whose join_month=3 is priority 1
  2. Employees whose address contains the string "Avenue" is priority 2
  3. Employees whose address contains the string "Street" is priority 3
  4. Employees whose address contains the string "Road" is priority 4

As of now, I'm at this stage:

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

I'm stuck at priority field. What should I put there?


回答1:


Using the aggregation framework you would "ideally" want to use the $regex filter within the $cond logical operator in the $project pipeline step but unfortunately MongoDB is yet to support this. There is a JIRA ticket for this currently open $project filter using $regex

However, a workaround (though not the best solution performant-wise) would be to use map-reduce. Consider populating a test collection:

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

Define your map function as:

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

The reduce function follows:

var reducer = function() { };

Then run the mapduce operation on the test collection and store the result in the collection mr_result

db.test.mapReduce(mapper, reducer, {
    "out": 'mr_result'
    "query": {
        "$or": [ 
            { "join_month": 3 }, 
            { "address": /.*Avenue.*/i }, 
            { "address": /.*Street.*/i }, 
            { "address": /.*Road.*/i }
        ] 
    }
})

Query the result collection:

db.mr_result.find().sort({ "priority": 1})

Sample Output

{ "_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 } }


来源:https://stackoverflow.com/questions/34740960/performing-priority-query-in-mongo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!