MongoDB:使用$ cond和$ regex进行聚合 [英] MongoDB: Aggregation using $cond with $regex

查看:1077
本文介绍了MongoDB:使用$ cond和$ regex进行聚合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图分多个阶段对数据进行分组.

I am trying to group data in multiple stages.

此刻,我的查询如下:

db.captions.aggregate([
{$project: {
    "videoId": "$videoId",
    "plainText": "$plainText",
    "Group1": {$cond: {if: {$eq: ["plainText", {"$regex": /leave\sa\scomment/i}]}, 
        then: "Yes", else: "No"}}}}
])

我不确定在聚合阶段是否可以在$ cond中使用$ regex运算符.非常感谢您的帮助!

I am not sure whether it is actually possible to use the $regex operator within a $cond in the aggregation stage. I would appreciate your help very much!

预先感谢

推荐答案

更新:从MongoDB v4.1.11开始,对于您的问题,终于出现了一个很好的解决方案,已记录在文档中此处.

UPDATE: Starting with MongoDB v4.1.11, there finally appears to be a nice solution for your problem which is documented here.

原始答案:

正如我在上面的评论中所写,到目前为止,$regex$cond内部不起作用.为此,有一个开放的 JIRA票证,但是它是开放的.

As I wrote in the comments above, $regex does not work inside $cond as of now. There is an open JIRA ticket for that but it's, err, well, open...

在您的特定情况下,我倾向于建议您在客户端解决该主题,除非您要处理大量的输入数据,而这些输入数据始终只会返回较小的子集.根据查询判断,您似乎总是要检索刚刚存储在两个结果组(是"和否")中的所有文档.

In your specific case, I would tend to suggest you solve that topic on the client side unless you're dealing with crazy amounts of input data of which you will always only return small subsets. Judging by your query it would appear like you are always going to retrieve all document just bucketed into two result groups ("Yes" and "No").

如果您不希望或无法在客户端解决该主题,那么这里使用的是

If you don't want or cannot solve that topic on the client side, then here is something that uses $facet (MongoDB >= v3.4 required) - it's neither particularly fast nor overly pretty but it might help you to get started.

db.captions.aggregate([{
    $facet: { // create two stages that will be processed using the full input data set from the "captions" collection
        "CallToActionYes": [{ // the first stage will...
            $match: { // only contain documents...
                "plainText": /leave\sa\scomment/i // that are allowed by the $regex filter (which could be extended with multiple $or expressions or changed to $in/$nin which accept regular expressions, too)
            }
        }, {
            $addFields: { // for all matching documents...
                "CallToAction": "Yes" // we create a new field called "CallsToAction" which will be set to "Yes"
            }
        }],
        "CallToActionNo": [{ // similar as above except we're doing the inverse filter using $not
            $match: {
                "plainText": { $not: /leave\sa\scomment/i }
            }
        }, {
            $addFields: {
                "CallToAction": "No" // and, of course, we set the field to "No"
            }
        }]
    }
}, {
    $project: { // we got two arrays of result documents out of the previous stage
        "allDocuments" : { $setUnion: [ "$CallToActionYes", "$CallToActionNo" ] } // so let's merge them into a single one called "allDocuments"
    }
}, {
    $unwind: "$allDocuments" // flatten the "allDocuments" result array
}, {
    $replaceRoot: { // restore the original document structure by moving everything inside "allDocuments" up to the top
        newRoot: "$allDocuments"
    }
}, {
    $project: { // include only the two relevant fields in the output (and the _id)
        "videoId": 1,
        "CallToAction": 1
    }
}])

与聚合框架一样,它可能有助于从管道末端删除各个阶段并运行部分查询,以便了解各个阶段的工作.

As always with the aggregation framework, it may help to remove individual stages from the end of the pipeline and run the partial query in order to get an understanding of what each individual stage does.

这篇关于MongoDB:使用$ cond和$ regex进行聚合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆