mongodb - 如何在 mongo 聚合 $group $cond 中使用 $in 或 $nin

标签 mongodb mongodb-query aggregation-framework

我想通过在属性上使用 $or 来实现 $sum 和 $cond:

db.collectionName.aggregate(
{
   "$group": {
     "_id":'$created_at',
     "count": {"$sum": 1},
     "count_failure": {
         "$sum": {
           "$cond": [
               {
                 "$id":
                  { "$in": [ 0,100,101,102,103,104,105 ] }
               }, 
               1,
               0
              ] 
           }
         }
    }  
 }
)

但错误提示:无效的运算符“$id”

语法有什么问题吗?或者我错误地编写了查询。

目前我正在通过以下方式实现这一目标:

db.collectionName.aggregate(
{
   "$group": {
     "_id":'$created_at',
     "count": {"$sum": 1},
     "count_failure": {
         "$sum": {
           "$cond": [
               {
                 "$or":[
                  { "$eq": [ "$id", 0 ] },
                  { "$eq": [ "$id", 100 ]},
                  { "$eq": [ "$id", 101 ]},
                  { "$eq": [ "$id", 102 ]},
                  { "$eq": [ "$id", 103 ]},
                  { "$eq": [ "$id", 104 ]},
                  { "$eq": [ "$id", 105 ]}
                 ]
               }, 
               1,
               0
              ] 
           }
         }
   }  
 }
)

最佳答案

$setIsSubset 上的比较是比您正在使用的 $or 条件更短的选项,尽管它对于您正在做的事情仍然基本上有效。

$setIsSubset 的唯一问题是每个参数都是一个数组,因此您需要将单个元素转换为单个元素数组。使用 $map 这很容易:

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$setIsSubset": [
                        { "$map": {
                            "input": ["A"],
                            "as": "el",
                            "in": "$id"
                        }},
                        [ 0,100,101,102,103,104,105 ],
                    ]},
                    1,
                    0
                ]
            }
        }
    }}    
])

或者,如果您愿意,可以将参数数组与奇异值进行匹配,即 $anyElementTrue :

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}},
                    1,
                    0
                ]
            }
        }
    }}
])

其中 $map 而是遍历参数以匹配单数,而不是将单数强制放入数组中。

当然,由于这两种形式本质上都是向 $cond 提供 true/false ,那么您可以使用 $not 反转逻辑。如有需要:

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$not": [{ "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}}]},
                    1,
                    0
                ]
            }
        }
    }}
])

这实际上取决于您如何看待它,但仅仅作为提供的参数,您实际上并没有通过 $or 获得任何超过原始形式的东西。它可能看起来更干净并且“更容易键入”,但通常我不会直接将此类逻辑“键入”到聚合管道中,而是首先基于简单列表生成结构的该部分:

var failList = [ 0,100,101,102,103,104,105 ];

var orCondition = failList.map(function(el) { 
    return { "$eq": [ "$id", el ] }
})

然后在管道定义中使用重新映射的数组内容:

    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$or": orCondition },
                    1,
                    0
                ]
            }
        }
    }}
])

无论您如何看待它,请记住它们都只是数据结构,并且您有基本的操作过程。无论是在管道加工内部,还是在管道施工本身。

关于mongodb - 如何在 mongo 聚合 $group $cond 中使用 $in 或 $nin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33734923/

相关文章:

c# - 如何从 C# Mongodb 强类型驱动程序中的文档加载特定字段

node.js - mongoosastic,无法创建映射

javascript - 在 mongodb 中实现分页

MongoDB MapReduce——是否有聚合替代方案?

mongodb - 如何在mongodb中找到两个日期之间的时差

javascript - 在 Node.js 中导出 Mongoose 代码 - 将值从 Mongoose 方法传递给回调

node.js - Nodejs 在特定时间后删除上传的文件

MongoDB:列表中的几个字段

javascript - 将默认值设置为 Node js中的mongoose数组

c# - MongoDB C# 2.0 驱动程序多次展开