【问题标题】:Query on array of arrays查询数组数组
【发布时间】:2020-12-03 14:34:32
【问题描述】:

我是 mongodb 的新手,并且在这个任务上卡住了一段时间。 我需要使用以下架构对集合执行查询:

{
  ticker: String,
  asks: [[Number]],
  bids: [[Number]],
  timestamp: String,
  datetime: String
}

这是文档示例:

  { 
    "_id" : ObjectId("5fc17630cf8dff0cd5506dc4"), 
    "asks" : [ 
      [ "23685.0", "0.008" ],
      [ "23688.8", "0.000" ],
      [ "23696.7", "0.000" ]
    ], 
    "bids" : [ 
      [ "23553.7", "0.200" ],
      [ "23557.8", "0.207" ],
      [ "23558.4", "0.045" ],
      [ "23563.4", "0.020" ] 
    ],
    "timestamp" : 1606514176211,
    "datetime" : "2020-11-27T21:56:16.211Z",
    "ticker" : "YFI/USDT"
  }

询价和出价的内部数组有两个元素:第一个元素是价格,第二个元素是数量。

我有两个问题:

  1. 我需要查询集合以获取价格大于基于日期时间字段的时间间隔的要价和出价(仅要价或仅出价)中的值的所有条目。 我试图弄乱 $elemMatch 和聚合框架,但到目前为止没有运气。

  2. 我的另一个问题是,在查询这些字段时,数组或数组字段类型是否是一个不错的选择。我希望有数百万条这种类型的记录。请建议是否添加索引和/或使用其他数据结构将这些数据保存在集合中。

非常感谢任何帮助。 谢谢。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    问题 1:

    您必须首先 $match 您的日期以仅返回您需要的时间间隔内的文档,然后 $filter 您的数组(询问或出价)以仅返回您需要的内容。

    这是查询(当然您可以对出价进行完全相同的操作):

    db.collection.aggregate([
      {
        "$match": {
          $expr: {
            "$and": [
              {
                "$gte": [
                  "$datetime",
                  "2020-11-01"
                ]
              },
              {
                "$lt": [
                  "$datetime",
                  "2020-12-01"
                ]
              }
            ]
          }
        }
      },
      {
        "$addFields": {
          "asks": {
            "$filter": {
              "input": "$asks",
              "as": "ask",
              "cond": {
                "$gte": [
                  {
                    "$toDouble": {
                      "$arrayElemAt": [
                        "$$ask",
                        0
                      ]
                    }
                  },
                  23686
                ]
              }
            }
          }
        }
      }
    ])
    

    You can test it here

    问题 2:

    但是,正如您所注意到的,这可能不是存储和查询数据的最佳方式。 我看到一些简单的事情需要改进:

    1- 用一个对象替换你的嵌套数组。直接查询对象字段而不是数组中的位置会更容易。

    {
      "price" : yourPrice, 
      "quantity":yourQuantity
    }
    

    2- 使用数字(int/double)而不是字符串,您将避免转换步骤,从而提高聚合的性能。

    {
      "price" : 21563, 
      "quantity":0.154
    }
    

    3-你真的需要日期和时间吗?如果没有,只需存储日期,这样您就可以在其上放置索引并在 $match 阶段利用它。

    Here's a sample of such a dataset/query

    【讨论】:

    • 感谢 matthPen!我想避免使用对象并使用数组来节省记录大小 - 有些记录可能填充了数百个内部数组,所以我认为在那里填充键是多余的。我将尝试在日期字段上添加索引,看看是否有任何区别。
    • 我会在测试解决方案后将您的答案标记为已解决。谢谢!
    • mongoplayground.net/p/Cg_QBzAa2qg 此代码仍然返回不符合结果集中的记录。
    • 不完全是我需要的,但这是一个好的开始。感谢帮助。我会玩它
    猜你喜欢
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2018-12-20
    • 2019-07-02
    相关资源
    最近更新 更多