Как рассчитать скользящее (скользящее) среднее, если между периодами отсутствуют даты, а размер окна Dynami c в MongoDB? - PullRequest
0 голосов
/ 04 мая 2020

У меня есть коллекция, которая содержит идентификатор, дату и значение. Однако у вас не будет записи для каждой даты для данного идентификатора. то есть см. ниже. Идентификатор не будет иметь значений для каждой даты (в данном случае ниже, значения не будут там 3 апреля, 5,5)

ID   Date         value 
1   2020-04-01     6
1   2020-04-02     2
1   2020-04-06     9

Моя проблема в том, как бы вы рассчитали перемещение (скользящее окно) средние значения за последние x дней (x - это динамический c - он будет меняться в зависимости от выбора пользователя - скажем, на данный момент 2), за этот период времени?

, если пользователь выбирает ID = 1, перемещается среднее окно за 2 дня и диапазон дат от 2020-04-01 до 2020-04-08, мой вывод должен выглядеть ниже

Date          Avg.Value
2020-04-01    6
2020-04-02    4
2020-04-03    1
2020-04-04    0
2020-04-05    0
2020-04-06    9
2020-04-07    4.5
2020-04-08    0

Я проследил за помощью нескольких постов в сообществе ( здесь ) и разработал запрос. Но запрос, который я разработал, не будет показывать результаты для дат 4, 5, 7, 8 апреля. Может ли кто-нибудь помочь мне разработать эффективный запрос в соответствии с моими требованиями к выводу? (Примечание: я могу даже принять, если даты 4, 5 и 8 апреля отсутствуют в выводе, это тоже нормально)

мой запрос ниже:

db.collection.aggregate([{
    '$match': {
        'id': "1",
        'dt': {
            '$lte': ISODate('2020-04-08'),
            '$gte': ISODate('2020-04-01')
        }
    }
}, {
    $sort: {
        dt: 1
    }
}

, {
    $group: {
        _id: "$id",
        prx: {
            $push: {
                v: "$value",
                d: "$dt"
            }
        }
    }
},
# generate missing dates between ranges available for that ID. i.e., generate Apr 3, 4,5
{
    $addFields: {
        "prx12": {
            $map: {
                input: {
                    $range: [0, {
                        $add: [{
                            $divide: [{
                                $subtract: [{
                                    $max: "$prx.d"
                                }, {
                                    $min: "$prx.d"
                                }]
                            }, 86400000]
                        }, 1]
                    }]
                },
                as: "x",
                in: {
                    $add: [{
                        $min: "$prx.d"
                    }, {
                        $multiply: [86400, 1000, "$$x"]
                    }]
                }
            }
        }
    }
},
# below block will group dates and value based on window size ( 2)
# for e.g, Apr 2 block will contain { Apr 1, 6} an {Apr 2, 2} 
{
    $addFields: {
        "prx": {
            $map: {
                input: {
                    $range: [0, {
                        $size: "$prx12"
                    }]
                },
                as: "z",
                in: {
                    total1: {
                        $filter: {
                            input: "$prx",
                            as: "num",
                            cond: {
                                $and: [{
                                    $gt: ["$$num.d", {
                                        $subtract: [{
                                            $arrayElemAt: ["$prx12", "$$z"]
                                        }, 1000 * 86400 * 2]  # 2 is window size
                                    }]
                                }, {
                                    $lte: ["$$num.d", {
                                        $arrayElemAt: ["$prx12", "$$z"]
                                    }]
                                }]
                            }
                        }
                    },
                    fd: {
                        $arrayElemAt: ["$prx12", "$$z"]
                    }
                }
            }
        }
    }
}, {
    $project: {
        "prx.total1": 1,
        "prx.fd": 1
    }
}, {
    "$unwind": "$prx"
}, {
    "$unwind": "$prx.total1"
}, {
    $group: {
        _id: "$prx.fd",
        res: {
            $sum: "$prx.total1.v"
        }
    }
}]).pretty()

Просто добавили запрос и комментарии для справки. Я был бы очень признателен, если бы кто-то мог помочь мне предложить или помочь мне в эффективном запросе? Заранее большое спасибо.

...