Я пытаюсь извлечь ohlc 5-минутный интервал из 1-минутного интервала DB, хранящегося в mongoDB. Ниже мой текущий запрос.
myModel.aggregate([
{"$project":
{
"data":
{
"$let":
{
"vars":
{
"mints":{"$arrayElemAt":[{"$arrayElemAt":["$data",0]},0]},
"maxts":{"$arrayElemAt":[{"$arrayElemAt":["$data",-1]},0]}
},
"in":
{
"$map":
{
"input":{"$range":["$$mints",{"$add":["$$maxts",300]},300]},
"as":"rge",
"in":
{
"$let":
{
"vars":
{
"five":
{
"$filter":
{
"input":"$data",
"as":"fres",
"cond":
{
"$and":
[
{"$gte":[{"$arrayElemAt":["$$fres",0]},"$$rge"]},
{"$lt":[{"$arrayElemAt":["$$fres",0]},{"$add":["$$rge",300]}]}
]
}
}
}
},
"in":
[
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},0]},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",0]},1]},
{"$max":{"$map":{"input":"$$five","as":"res","in":{"$arrayElemAt":["$$res",2]}}}},
{"$min":{"$map":{"input":"$$five","as":"res","in":{"$arrayElemAt":["$$res",3]}}}},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},-2]},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},-1]}
]
}
}
}
}
}
}
}
}
]);
Кажется, он извлекает 5 минут, но не заботится о пробелах за 1-минутный интервал данных. Вместо этого для тех моментов времени я получаю нулевой массив. Как нам избежать нулевых массивов?
Пример 1 Данные БД: https://gist.github.com/parthi2929/36e6898cff7be45ccdd008ec750e70e9
5 минут извлеченного моментального снимка здесь
Как вы можете видеть в снимке, я получаю множество нулевых массивов. Как мне их избежать?
Я попытался вставить { "$ne":[{"$arrayElemAt":["$$fres",0]},null] }
в $ и операторе, но это не помогло.
Обновление 14 февраля 2018 года: согласно предложению Veeram ниже приведен модифицированный код, включенный в предлагаемые изменения. Тем не менее, я все еще получаю один пустой массив (это, по-видимому, много пустых массивов, в этот промежуток времени теперь нет, но заменен одним пустым массивом), который также должен быть исправлен.
db.getCollection('ohlc-koinex-1').aggregate(
[
{"$project":
{
"data":
{
"$let":
{
"vars":
{
"mints":{"$arrayElemAt":[{"$arrayElemAt":["$data",0]},0]},
"maxts":{"$arrayElemAt":[{"$arrayElemAt":["$data",-1]},0]}
},
"in":
{
"$setDifference":
[
{
"$map":
{
"input":{"$range":["$$mints",{"$add":["$$maxts",300]},300]},
"as":"rge",
"in":
{
"$let":
{
"vars":
{
"five":
{
"$filter":
{
"input":"$data",
"as":"fres",
"cond":
{
"$and":
[
{"$gte":[{"$arrayElemAt":["$$fres",0]},"$$rge"]},
{"$lt":[{"$arrayElemAt":["$$fres",0]},{"$add":["$$rge",300]}]}
]
}
}
}
},
"in":
{
"$cond":[
{"$eq":["$$five",[]]},
"$$five",
[
{"$arrayElemAt": [{"$arrayElemAt":["$$five",-1]},0]},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",0]},1]},
{"$max":{"$map":{"input":"$$five","as":"res","in":{"$arrayElemAt":["$$res",2]}}}},
{"$min":{"$map":{"input":"$$five","as":"res","in":{"$arrayElemAt":["$$res",3]}}}},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},-2]},
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},-1]}
]
]
}
}
}
}
},[]
]
}
}
}
}
}
]
)
Вот снимок результата
Вы можете добавить $cond
operator для учета пробелов, за которыми следует $filter
чтобы отфильтровать значения пустых массивов.
Вам потребуются два изменения.
Первое изменение для хранения значений [] для пробелов вместо массива с нулевыми значениями.
Обновите внутреннее выражение $ let ниже:
{
"$let":{
"vars":{"five":...},
"in":{
"$cond":[
{"$eq":["$$five",[]]},
"$$five",
[{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},0]},
....
{"$arrayElemAt":[{"$arrayElemAt":["$$five",-1]},-1]}]
]
}
}
}
Второе изменение для фильтрации пустых значений массива на выходе.
{
"$project":{
"data":{
"$let":{
"vars":{"mints":...},
"in":{"$filter":{"input":{"$map":...},as:"flr", "cond":{"$ne":["$$flr",[]]}}}
}
}
}
}