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

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

问题描述

我正在尝试在多个阶段对数据进行分组.

I am trying to group data in multiple stages.

目前我的查询如下所示:

At the moment my query looks like this:

db.captions.aggregate([
{$project: {
    "videoId": "$videoId",
    "plainText": "$plainText",
    "Group1": {$cond: {if: {$eq: ["plainText", {"$regex": /leavesascomment/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").

如果您不想或无法在客户端解决该主题,那么这里有一些使用 $facet(需要 MongoDB >= v3.4)——它既不是特别快也不是特别漂亮,但它可能会帮助您入门.

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": /leavesascomment/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: /leavesascomment/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天全站免登陆