集合中的每个“第n个”文档-MongoDB + NodeJS

时间:2019-02-04 07:32:26

标签: node.js mongodb

我正在寻找一种方法来返回存储在MongoDB中的不同分辨率的数据。我能想到的最优雅的解决方案是查询,该查询返回集合中每个'nth'(第二,第三,第十等)文档。

我每隔5秒存储一次数据(例如温度),但希望查看数据的不同趋势。

要找到瞬时趋势,我查看了最后720个条目(1小时)。这部分很简单。

如果我想看一点更长的趋势,比如说3个小时,我可以检索最近的2160项(3个小时),但是那是从服务器提取更多时间的时间,并且需要更多的时间和内存来进行绘图。就像查看较大趋势时一样,较小的移动比较杂乱,我最好检索相同数量的文档(720),但每3次只检索一次,仍然给我3个小时的结果,并且使用相同的资源详细牺牲。

当我要查看几周(120,960个文档)或几个月(500,000多个文档)时,这变得更加极端。

我当前的代码收集每个文档(n = 1):

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div name="div" id="a" style="background-color:green; font-size:20px">aaaa</div>
<span id="b" name="span" style="background-color:blue;font-size:27px">bbb</span>

然后,我可以遍历返回的数组并在以下情况下删除每个文档:

db.collection(collection).find().sort({$natural:-1}).limit(limit)

这至少使客户端不必处理所有数据,但是这似乎效率极低,我宁愿数据库处理这部分。

有人知道实现此目的的方法吗?

3 个答案:

答案 0 :(得分:0)

Apparenlty,mongo中没有内置的解决方案可以解决您的问题。

前进的道路是将数据智能地分段存储。

因此,您可以将数据存储在一个集合中,该集合最多容纳每周或每月的数据。一个新的月/周意味着将您的数据存储在另一个集合中。这样,您就不会进行全表扫描,也不会像问题中提到的那样收集每个文档。您的应用程序代码将决定要查询哪个集合。

如果我不满意,我会使用其他工具,因为mongo更适合于通用数据库。像cassandra这样的数据库可以很好地处理时间序列数据(每5秒存储一次),就像您的情况一样,它可以轻松地处理频繁的写入操作。

备用碎片(更新): 始终将当前数据写入集合“ week0”中,并在后台运行每周调度程序,以将数据从“ week0”移至历史记录集合“ week1”,“ week2”,依此类推。分段逻辑取决于您的要求。

答案 1 :(得分:0)

我认为$ bucket阶段可能会帮助您。 您可以做类似的事情

db.collection.aggregate([
  {
    $bucketAuto: {
      groupBy: "$_id", // here you'll put the variable you need, in your example 'temperature'
      buckets: 5 // this is the number of documents you want to return, so if you want a sample of 500 documents, you can put 500 here
    }
  }
])

上述查询结果中的每个文档都是这样的

    "_id": {
      "max": 3,
      "min": 1
    },
    "count": 2

如果您已按温度分组,则每个文档将具有该样本中的最低和最高温度

答案 2 :(得分:0)

您可能还有其他问题。 Docs声明不依赖自然顺序:

  

此排序是内部实施功能,您应该   不依赖于其中的任何特定结构。

您可以改为将每个纪元秒保存在每个文档中,并在查询中使用限制和排序对它进行模算。