【问题标题】:pymongo group multiple conditionspymongo 分组多个条件
【发布时间】:2020-12-19 10:51:09
【问题描述】:
CURRENT_TZ = timezone(bp.BaseModel.__timezone__ or "Asia/Shanghai")
NOW = CURRENT_TZ.localize(datetime.utcnow())
EXPIRY_DATE = NOW + relativedelta(days=5)

res = await Fixture.aggregate(
        [
            {"$match": dict(eol={"$nin": [True, ""]})},
            {
                "$group": {
                    "_id": {
                        "$cond": [
                            {"$lt": ["pm_date", start_date]},
                            "PENDING",
                            {
                                "$gte": ["pm_date", start_date],
                                "$lt": ["pm_date", end_date],
                            },
                            "DONE",
                            {
                                "$gte": ["pm_due_date", start_date],
                                "$lte": ["pm_due_date", EXPIRY_DATE],
                            },
                            "WILL EXPIRED",
                            {"$lte": ["pm_due_date", NOW]},
                            "EXPIRED",
                        ]
                    },
                    "count": {"$sum": 1},
                }
            },
        ]
    )

从上面的代码中,我期望输出例如

{
    "_id" : "PENDING",
    "qty": 50 
}, 
{
     "_id" : "DONE",
     "qty": 50
},
{
    "_id" : "WILL BE EXPIRE",
    "qty": 40 
}
{
    "_id" : "EXPIRED",
    "qty": 10
}

但是从我的控制台显示错误如下,有人可以帮我修复 pymongo 管道以探索多个条件吗?

raise OperationFailure(msg % errmsg, code, response) pymongo.errors.OperationFailure:表示表达式的对象必须只有一个字段:{ $gte: [ "pm_date", new Date(1596240000000) ], $lt: [ "pm_date", new Date(1598918400000) ] } em>

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    您应该将$cond 放在$project 阶段而不是$group

    [
        {"$match": dict(eol={"$nin": [True, ""]})},
        {"$project": {
            "status": {
               "$cond": [
                   {"$lt": ["pm_date", start_date]},
                   "PENDING",
                   {"$cond": [
                       {
                            "$and": [
                               {"$gte": ["pm_date", start_date]},
                               {"$lt": ["pm_date", end_date]}
                            ]
                        },
                       "DONE",
                       {"$cond": [
                                {
                                    "$and": [
                                        {"$gte": ["pm_date", start_date]},
                                        {"$lt": ["pm_date", EXPIRY_DATE]}
                                    ]
                                },
                                    "WILL EXPIRED",
                                    "EXPIRED"
                       ]}
                  ]}
             ]}
           }
      },
      {
           "$group": {
               "_id": "$status",
               "count": {"$sum": 1},
           }
      },
    

    ]

    【讨论】:

    • 感谢您的反馈,但似乎不起作用(错误:pymongo.errors.OperationFailure:表示表达式的对象必须只有一个字段:{ $gte: [ "pm_date", new Date(1598918400000) ], $lt: [ "pm_date", new Date(1601510400000) ] } )
    • 我更新了答案,$cond 运算符有问题
    【解决方案2】:

    更新:我使用 $switch (aggregation) 得到了结果 参考:https://docs.mongodb.com/manual/reference/operator/aggregation/switch/

    res = await Fixture.aggregate(
            [
                {"$match": dict(eol={"$nin": [True, ""]})},
                {
                    "$project": {
                        "pm_due_date": 1,
                        "status": {
                            "$switch": {
                                "branches": [
                                    {
                                        "case": {"$lt": ["$pm_due_date", NOW]},
                                        "then": "EXPIRED",
                                    },
                                    {
                                        "case": {
                                            "$and": [
                                                {
                                                    "$gte": [
                                                        "$pm_due_date",
                                                        start_date,
                                                    ]
                                                },
                                                {
                                                    "$lte": [
                                                        "$pm_due_date",
                                                        EXPIRY_DATE,
                                                    ]
                                                },
                                            ]
                                        },
                                        "then": "WILL EXPIRE",
                                    },
                                    {
                                        "case": {"$lt": ["$pm_date", start_date]},
                                        "then": "PENDING",
                                    },
                                    {
                                        "case": {
                                            "$and": [
                                                {"$gte": ["$pm_date", start_date]},
                                                {"$lt": ["$pm_date", end_date]},
                                            ]
                                        },
                                        "then": "DONE",
                                    },
    
                                ],
                                "default": "NA",
                            }
                        },
                    }
                },
                {"$group": {"_id": "$status", "count": {"$sum": 1}}},
            ]
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      • 2021-07-08
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 2013-06-22
      相关资源
      最近更新 更多