【问题标题】:How to avoid time gaps while aggregating OHLC in mongoDB如何在 mongoDB 中聚合 OHLC 时避免时间间隔
【发布时间】:2018-07-24 23:01:03
【问题描述】:

我正在尝试从存储在 mongoDB 中的 1 分钟间隔数据库中提取 ohlc 5 分钟间隔。以下是我当前的查询。

    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分钟提取的输出快照是here

正如您在快照中看到的,我得到了很多空数组。如何避免它们?

我尝试在 $and 运算符中插入 { "$ne":[{"$arrayElemAt":["$$fres",0]},null] },但没有帮助。

2018 年 2 月 14 日更新:根据 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]}
                                    ]
                                ]
                             }
                          }
                        }
                      }
                  },[]
                 ]
            }
          }
        }
      }
    }
]
)

Here 是结果的快照

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    您可以添加$cond 运算符来解决空白,然后添加$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",[]]}}}
          }
        }
      }
    }
    

    【讨论】:

    • 非常感谢 veeram。不过是小问题。间隙之间的所有空数组都消失了,但现在由一个空数组代替,如我在上面更新的问题中所示。你能检查一下吗?
    • Yw.Updated 用 $filter 替换 setDifference 的答案。应该按预期工作。
    猜你喜欢
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多