【问题标题】:Regex in MongoDB's $cond or $switch condition expression?MongoDB $cond 或 $switch 条件表达式中的正则表达式?
【发布时间】:2023-03-07 23:32:01
【问题描述】:

对于这样的收藏

{ _id: 1, name: "novel_1", qty: 15}
{ _id: 2, name: "magazine_1", qty: 5}
{ _id: 3, name: "novel_2", qty: 5}
{ _id: 4, name: "guitar_1", qty: 10}
{ _id: 5, name: "violin_1", qty: 10}

我想以某种方式使用 $project 管道根据项目名称对项目进行分类。然后从中得到一个分组计数。

db.items.aggregate([
    {$project: {category: {
        $switch: {
            branches: [
                // use regex here to categorize the items by their name
                {case: {$in: ['$name', [/magazine/, /novel/]]},
                    then: 'book'},
                {case: {$in: ['$name', [/guitar/, /violin/]]},
                    then: 'instrument'}
            ],
            default: 'others'
        }
    }}},
    // get the group-by count based on the category
    {$group: {
        _id: {category: '$category'},
        count: {$sum: '$qty'}
    }}
]);

然而,MongoDB 似乎不支持 $project 管道中的正则表达式条件表达式。那么我们如何进行这种先变换后分组查询呢?我想一种方法是通过 MapReduce,但据说性能不是很好。特别是我在我的应用程序中使用 python,使用 MapReduce 会将 JS 代码和 python 代码缠在一起。

【问题讨论】:

    标签: python mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您不需要 MapReduce。您可以使用聚合框架来执行此操作。

    另外注意,你不需要先$project你的文档,你可以将$switch表达式传递给_id

    db.items.aggregate(
        [
           {
              "$group": {
                 "_id": {
                    "$switch": {
                       "branches": [
                          {
                             "case": {
                                "$or": [
                                   {
                                      "$gt": [
                                         {
                                            "$indexOfCP": [
                                               "$name",
                                               "magazine"
                                            ]
                                         },
                                         -1
                                      ]
                                   },
                                   {
                                      "$gt": [
                                         {
                                            "$indexOfCP": [
                                               "$name",
                                               "novel"
                                            ]
                                         },
                                         -1
                                      ]
                                   }
                                ]
                             },
                             "then": "book"
                          },
                          {
                             "case": {
                                "$or": [
                                   {
                                      "$gt": [
                                         {
                                            "$indexOfCP": [
                                               "$name",
                                               "violin"
                                            ]
                                         },
                                         -1
                                      ]
                                   },
                                   {
                                      "$gt": [
                                         {
                                            "$indexOfCP": [
                                               "$name",
                                               "guitar"
                                            ]
                                         },
                                         -1
                                      ]
                                   }
                                ]
                             },
                             "then": "instrument"
                          }
                       ],
                       "default": "others"
                    }
                 },
                 "count":{"$sum": "$qty"}
              }
           }
        ]
    )
    

    db.items.aggregate(
        [
           {
              "$group": {
                 "_id": {
                    "$switch": {
                       "branches": [
                          {
                             "case": {
                                "$gt": [
                                   {
                                      "$size": {
                                         "$setInterserction": [
                                            {
                                               "$split": [
                                                  "$name",
                                                  "-"
                                               ]
                                            },
                                            [
                                               "magazine",
                                               "novel"
                                            ]
                                         ]
                                      }
                                   },
                                   0
                                ]
                             },
                             "then": "book"
                          },
                          {
                             "case": {
                                "$gt": [
                                   {
                                      "$size": {
                                         "$setInterserction": [
                                            {
                                               "$split": [
                                                  "$name",
                                                  "-"
                                               ]
                                            },
                                            [
                                               "guitar",
                                               "violin"
                                            ]
                                         ]
                                      }
                                   },
                                   0
                                ]
                             },
                             "then": "instrument"
                          }
                       ],
                       "default": "others"
                    }
                 },
                 "count": {"$sum": "$qty"}
              }
           }
        ]
    )
    

    【讨论】:

    • 感谢您的解决方案!这是一种非常有用的聚合技术。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 2011-10-30
    • 1970-01-01
    • 2012-01-20
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多