regex - MongoDB:使用 $cond 和 $regex 进行聚合

标签 regex mongodb conditional aggregation-framework grouping

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

目前我的查询是这样的:

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

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

提前致谢

最佳答案

更新:从 MongoDB v4.1.11 开始,终于有一个很好的解决方案来解决您的问题,记录在案 here .


原答案:

正如我在上面的评论中所写,$regex 目前在 $cond 中不起作用。有一个开放的JIRA ticket为此,但它是,呃,好吧,开放...

在您的具体情况下,我倾向于建议您在客户端解决该主题,除非您处理的是大量输入数据,而您总是只返回其中的一小部分。根据您的查询判断,您似乎总是要检索所有刚刚分入两个结果组("is"和“否”)的文档。

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

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

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

关于regex - MongoDB:使用 $cond 和 $regex 进行聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49658581/

相关文章:

c# - 带分隔符的字节正则表达式

mysql - MySQL 中两种模式匹配形式的区别

MongoDB/NoSQL : Keeping Document Change History

r - 有条件地从数据框中删除行(多个条件)

r - 条件求和 (R)

python - 条件 If 语句 : If value in row contains string . .. 设置另一列等于字符串

regex - 如何根据行的特殊部分对文件的行进行排序

java - 除 | 之外的所有符号的正则表达式

node.js - 在 nodejs mongodb 中创建 Array 对象

java - 如何在Spring Boot中从另一个集合获取数据