Как рассчитать сумму с помощью conditional?

python-3.x #mongodb #mongoengine

#python-3.x #mongodb #mongoengine

Вопрос:

У меня есть такие документы в MongoDB:

 {
    "_id":{
        "$oid":"614e0f8fb2f4d8ea534b2ccb"
    },
    "userEmail":"abc@example.com",
    "customId":"abc1",
    "amountIn":10,
    "amountOut":0,
    "createdTimestamp":1632505743,
    "message":"",
    "status":"ERROR",
}
 

amountOut Поле может быть 0 , или положительным числовым значением.
Мне нужно вычислить сумму полей amountIn and amountOut только в том случае, если она положительна.
На данный момент я делаю это так:

 query = {
    'createdTimestamp': {'$gte': 1632430800},
    'createdTimestamp': {'$lte': 1632517200}
}
records = db.RecordModel.objects(__raw__=query).all()

total_amount = 0
for record in records:
    if record.amountOut > 0:
        total_amount  = record.amountOut
    else:
        total_amount  = record.amountIn
 

Но это очень медленно.
Я знаю mongoengine , что есть sum метод:

 total_amount = db.PaymentModel.objects(__raw__=query).sum('amountIn')
 

Но я не знаю, как использовать условие для этого метода.
Может быть, есть какие-то другие способы рассчитать сумму с условием, которое мне нужно быстрее?

Комментарии:

1. Это то, что вы ищете?

2. @ray да, похоже, это то, что мне нужно, но как мне это использовать mongoengine ?

Ответ №1:

Вы можете использовать api агрегации mongoengine, который просто позволяет вам выполнять агрегации в обычном режиме.

Теперь вы можете использовать этот конвейер в коде, который использует $cond :

 query = {
    'createdTimestamp': {'$gte': 1632430800, '$lte': 1632517200},
}
pipeline = [
    {"$match": query},
    {
        "$group": {
            "_id": None,
            "total_amount": {
                "$sum": {
                    "$cond": [
                        {
                            "$gt": [
                                "$amountOut",
                                0
                            ]
                        },
                        "$amountOut",
                        "$amountIn"
                    ]
                }
            }
        }
    }
]

records = db.RecordModel.objects().aggregate(pipeline)
 

Игровая площадка Mongo