简体   繁体   English

pymongo 组多个条件

[英]pymongo group multiple conditions

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

from the above code, I expected output for example like从上面的代码中,我期望输出例如

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

but from my console show error as following, can someone help me fix the pymongo pipeline for groping multiple conditions?但是从我的控制台显示如下错误,有人可以帮我修复 pymongo 管道以探索多个条件吗?

raise OperationFailure(msg % errmsg, code, response) pymongo.errors.OperationFailure: An object representing an expression must have exactly one field: { $gte: [ "pm_date", new Date(1596240000000) ], $lt: [ "pm_date", new Date(1598918400000) ] } raise OperationFailure(msg % errmsg, code, response) pymongo.errors.OperationFailure:表示表达式的对象必须只有一个字段:{ $gte: [ "pm_date", new Date(1596240000000) ], $lt: [ "pm_date ", 新日期(1598918400000) ] }

You should put your $cond in a $project stage instead of the $group你应该把你的$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},
       }
  },

] ]

Update: I got the result by using $switch (aggregation) Refer to: https://docs.mongodb.com/manual/reference/operator/aggregation/switch/更新:我通过使用$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}}},
        ]
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM