是否可以在 MongoDB 中的 $cond 中编写正则表达式

is it possible to write regular expression in $cond in MongoDB

我需要用$cond来合并differenet列,我需要写的一个$cond如下:

create_widget: {
        $sum:{
          $cond:[{$and: [ {$eq: ['$Method', 'POST']},
                {Url:{$regex: /.*\/widgets$/}} ]}, 1, 0]
        }
    }

而且这段代码不对,好像正则表达式不能放here.Is还有什么办法吗?我想匹配 Url 和正则表达式并将代码放在 $cond.

样本数据看起来像

{"BrandId":"a","SessionId":"a1","Method":"POST","Url":"/sample/widgets"}
{"BrandId":"a","SessionId":"a2","Method":"POST","Url":"/sample/blog"}
{"BrandId":"b","SessionId":"b1","Method":"PUT","Url":"/sample/widgets"}

我写的全部代码如下:

db.tmpAll.aggregate([
    {$group: {
        _id: {BrandId:'$BrandId'},
        SessionId: {$addToSet: '$SessionId'},
        create_widget: {
            $sum:{
              $cond:[{$and: [ {$eq: ['$Method', 'POST']},
                    {} ]}, 1, 0]
            }
        }
    }},
    {$group: {
        _id: '$_id.BrandId',
        distinct_session: {$sum: {$size: '$SessionId'}},
        create_widget: {$sum: '$create_widget'}
    }}
]);

示例代码的预期结果是

{ "_id" : "a", "distinct_session" : 2, "create_widget" : 1 }
{ "_id" : "b", "distinct_session" : 1, "create_widget" : 0 }

对于 MongoDB 4.2 和更新的生产版本,以及在 4.1.11 和更新的开发版本中,使用可用于正则表达式的 $regexMatch which is a syntactic sugar on top of $regexFind匹配和捕获。

db.tmpAll.aggregate([
    { "$group": {
        "_id": {
            "BrandId": "$BrandId",
            "SessionId": "$SessionId"
        },
        "widget_count": {
            "$sum": { 
                "$cond": [
                    {
                        "$and": [ 
                            { "$eq": ["$Method", "POST"] },
                            { "$regexMatch": { 
                                "input": "$Url",
                                "regex": /widget/
                            } } 
                        ]
                    }, 1, 0
                ]                     
            }
        },
        "session_count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.BrandId",
        "create_widget": { "$sum": "$widget_count" },
        "distinct_session": { "$sum": "$session_count" }
    } }
]);

SERVER-8892 - Use $regex as the expression in a $cond 有一个未解决的 JIRA 问题。但是,作为解决方法, 对于没有上述功能的旧 MongoDB 版本,请在聚合管道中使用以下解决方法。

它使用 $substr operator in the $project 运算符阶段来提取 URL 的部分,并作为正则表达式的解决方法。 :

db.tmpAll.aggregate([
    { "$group": {
        "_id": {
            "BrandId": "$BrandId",
            "SessionId": "$SessionId"
        },
        "widget_count": {
            "$sum": { 
                "$cond": [
                   {
                       "$and": [ 
                           { "$eq": ["$Method", "POST"] },
                           { "$eq": [ { "$substr": [ "$Url", 8, -1 ] }, "widget"] } 
                       ]
                   }, 1, 0
                ]                     
           }
        },
        "session_count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.BrandId",
        "create_widget": { "$sum": "$widget_count" },
        "distinct_session": { "$sum": "$session_count" }
    } }
]);

输出

/* 1 */
{
    "result" : [ 
        {
            "_id" : "a",
            "create_widget" : 1,
            "distinct_session" : 2
        }, 
        {
            "_id" : "b",
            "create_widget" : 0,
            "distinct_session" : 1
        }
    ],
    "ok" : 1
}