【问题标题】:How to take data N samples from MongoDB to form a graph representation on whole data set?如何从 MongoDB 中获取数据 N 个样本以形成整个数据集的图形表示?
【发布时间】:2019-12-07 03:43:26
【问题描述】:

这是我们新应用中的一个示例文档,用于在 MongoDB 子文档中存储时间序列数据,

{
    "_id" : ObjectId("5dcb6cacfb315e66b551a1a0"),
    "youtubeId" : "bIWShN9rKQU",
    "views" : [ 
        {
            "count" : 17506,
            "at" : ISODate("2019-08-12T13:31:00.002Z")
        }, 
        {
            "count" : 29576,
            "at" : ISODate("2019-11-14T13:32:00.216Z")
        }, 
        {
            "count" : 29579,
            "at" : ISODate("2019-11-15T13:33:00.197Z")
        }, 
        {
            "count" : 29582,
            "at" : ISODate("2019-11-16T13:34:00.192Z")
        }, 
        {
            "count" : 29586,
            "at" : ISODate("2019-11-17T13:35:00.180Z")
        }, 
        {
            "count" : 29595,
            "at" : ISODate("2019-11-19T13:36:00.190Z")
        }, 
        {
            "count" : 29597,
            "at" : ISODate("2019-11-20T13:37:00.206Z")
        }, 
        {
            "count" : 29604,
            "at" : ISODate("2019-11-21T13:38:00.228Z")
        }, 
        {
            "count" : 29606,
            "at" : ISODate("2019-11-22T13:39:00.218Z")
        }, 
        {
            "count" : 29613,
            "at" : ISODate("2019-11-24T13:40:00.201Z")
        }, 
        {
            "count" : 29619,
            "at" : ISODate("2019-11-25T13:41:00.250Z")
        }, 
        {
            "count" : 29624,
            "at" : ISODate("2019-11-27T13:42:00.103Z")
        }, 
        {
            "count" : 29636,
            "at" : ISODate("2019-11-29T13:43:00.128Z")
        }
    ]
}

现在,我想在移动应用程序使用的 Web 服务中发送这些数据以绘制图形,但我只想在 views 数组中获取 10 个对象,这应该是整个数据集的表示关于时间。但不管数组的大小,它应该是 10 个数据。

如何通过使用at 时间戳字段从整个数据集中获取 10 个数据来创建整个数据的表示?

【问题讨论】:

  • 你能解释一下这些是什么意思吗:“......我想在视图数组中只获取 10 个对象......”,“但它应该是 5 个数据,无论大小如何数组”和“如何从整个数据集中获取 10 个数据...”。可以举个例子吗?
  • @prasad_ 在上面的示例中,views 是一个对象数组,它的时间从 2019-08-12T13:31:00.002Z 到 2019-11-29T13:43:00.128Z(13 条记录为 1 / 分钟),因此 5 个样本意味着大约每 2 分钟一个记录
  • 我发布了一个聚合查询;请告诉我它是如何工作的。

标签: mongodb time-series aggregation-framework timeserieschart


【解决方案1】:

在上面的例子中,views 是一个对象数组,它的时间从 2019-08-12T13:31:00.002Z 到 2019-11-29T13:43:00.128Z(13 条记录为 1/ 分钟),因此其中的 5 个样本意味着每 2 个记录一个记录 分钟左右

var noOfSamples = 5

db.test.aggregate( [
{ 
  $addFields: { 
      indexes: { 
          $range: [ 0, 
                    { $size: "$views" }, 
                    { $ceil: { $divide: [ { $size: "$views" }, noOfSamples ] } } 
                  ]
      } 
  }
},
{ 
  $project: { 
      sample: { 
          $map: {
              input: "$indexes",
                 as: "ix",
                 in: { $arrayElemAt: [ "$views", "$$ix" ] }
          }
      }
   }
}
] )



注意事项:

您想要的样本数为 5,noOfSamplesviews 数组的大小为13

views 中的元素个数除以noOfSamples;在这种情况下,您将获得 2.6 的值。 $ceil 将其舍入为下一个舍入整数,即 3(我们称之为“步骤”)。 $range 运算符为您提供一个介于 0 和 12 之间的数字数组,步长为 3(0 是 views 数组的第一个索引,12 是数组的最高索引)。在聚合的第一阶段,您将获得一个名为 indexes:[ 0, 3, 6, 9, 12 ] 的数组。

在聚合的第二阶段,您使用上一阶段生成的indexes,通过它们的索引获取views 数组元素。 $map 聚合数组运算符映射indexes 生成的索引到 views 数组元素 - 因此您可以从 views 数组中获取五个元素作为样本。

【讨论】:

  • 这个答案真的很棒,如果你能解释一下逻辑真的会很有帮助吗?
  • 我在答案中添加了一些细节作为“注释”。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
  • 2021-10-29
  • 2017-05-08
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
相关资源
最近更新 更多