MongoDB与条件完全匹配

时间:2017-03-01 16:00:11

标签: mongodb mongodb-query aggregation-framework

我已经创建了这个URI集合和一个允许我传递URI和httpMethod的函数,它构建一个MongoDB查询来查找匹配的文档。问题是URI可以包含动态元素......就像这样:

/api/v1/users/{userid}/profile

但是也可以有这样的URI:

/api/vi/users/all/

我在收集中阻止了我的URI,所以我写了这个Mongo查询:

db.apis.aggregate({
    "$match" : {
        "$and" : [ 
            {"$or" : [{"_uri_.blocks.block" : "api","_uri_.blocks.position" : {"$eq" : 1.0}},{"_uri_.blocks.isWild" : true,"_uri_.blocks.position" : {"$eq" : 1.0}}]}, 
            {"$or" : [{"_uri_.blocks.block" : "v1","_uri_.blocks.position" : {"$eq" : 2.0}},{"_uri_.blocks.isWild" : true,"_uri_.blocks.position" : {"$eq" : 2.0}}]}, 
            {"$or" : [{"_uri_.blocks.block" : "users","_uri_.blocks.position" : {"$eq" : 3.0}},{"_uri_.blocks.isWild" : true,"_uri_.blocks.position" : {"$eq" : 3.0}}]}, 
            {"$or" : [{"_uri_.blocks.block" : "{userid}","_uri_.blocks.position" : {"$eq" : 4.0}},{"_uri_.blocks.isWild" : true,"_uri_.blocks.position" : {"$eq" : 4.0}}]}, 
            {"$or" : [{"_uri_.blocks.block" : "profile","_uri_.blocks.position" : {"$eq" : 5.0}},{"_uri_.blocks.isWild" : true,"_uri_.blocks.position" : {"$eq" : 5.0}}]}, 
            {"_canonical_._httpMethod_":"POST"}
        ]
    }
},
    {"$limit" : 1.0})

但它似乎并没有像我希望的那样完全匹配。

关于如何查询Mongo只能返回最准确的文档的任何建议?

1 个答案:

答案 0 :(得分:0)

您可以使用$regex来匹配模式,并采用以下输入:

db.apis.insert([{
    "uri": "/api/v1/users/someUser/profile"
}, {
    "uri": "/api/v2/users/otherUser/profile"
}, {
    "uri": "/api/v2/users/otherUser/login"
}, {
    "uri": "/api/v1/users/someUser/login"
}, {
    "uri": "/api/v1/users/all/"
}])
  • 匹配/api/v{version}/users/{userId}/profile

    var userId = "someUser";
    var version = 1;
    var limit = 1;
    
    db.apis.find({
        "uri": {
            $regex: '/api/v' + version + '/users/' + userId + '/profile'
        }
    }).limit(limit)
    
  • 匹配/api/v{version}/*

    var version = 1;
    var limit = 10;
    
    db.apis.find({
        "uri": {
            $regex: '/api/v' + version + '/.*'
        }
    }).limit(limit)