Mongodb文件的插入顺序

时间:2015-03-14 09:11:52

标签: node.js mongodb mongoose

我有一个用于跟踪用户审核数据的mongodb集合。所以基本上这将是数百万份文件。

审核由loginID(用户)及其对项目的活动进行跟踪。例如:userA在日期/时间修改了“第13项”。

案例:我需要根据用户和项目查询过滤器。那很简单。这会返回每个项目数千个文档。我需要按最新日期/时间(降序)列出它们。

问题:如何将新文档插入堆栈顶部? (像上限集合)或者是否可以从堆栈底部找到记录? (相反的顺序)。我不喜欢查找和排序的想法,因为在处理数以千万计的文档时,排序是一个瓶颈。

任何解决方案?

Stack:mongodb,node.js,mongoose。

谢谢!

2 个答案:

答案 0 :(得分:3)

  

堆栈的顶部?

你暗示有一个堆栈,但没有 - 有一棵树,或者更确切地说,是一棵B树。

  

我不喜欢查找和排序的想法

所以你想排序而不排序?这似乎没有多大意义。堆栈本质上是内存中的数据结构,它们在磁盘上不能很好地工作,因为它们需要巨大的连续块(​​实际上,大量堆栈在内存中甚至不能很好地工作,并且不断增长的堆栈需要复制整个数据集,几乎没有工作

  

排序是一个瓶颈

不应该,至少不是紧密存储在一起的数据(数据位置)。排序是一个O(m log n)操作,由于_id字段已经对时间戳进行编码,因此您已经有一个可以排序的字段。 m相对较小,所以我在这里看不到问题。你有没有尝试过?使用MongoDB 3.0,索引交叉变得更强大,您甚至可能在复合索引中不需要_id

在我的机器上,如果数据在RAM中,从索引过滤的大型集合中的顶级项目需要1ms ("executionTimeMillis" : 1)。纯粹的网络开销将在同一个联盟中,即使在localhost上也是如此。我使用简单的network creation tool创建了数据,并在mongo控制台中查询了它。

答案 1 :(得分:0)

我遇到了同样的问题。我的解决方案是创建另一个保留前10条记录的附加集合。好的一点是,您可以快速查询。不好的一点是你需要更新额外的收藏。

我发现this启发了我。我用ruby + mongoid实现了我的解决方案。

我的解决方案:

集合定义

class TrainingTopRecord
  include Mongoid::Document

  field :training_records, :type=>Array

  belongs_to :training

  index({training_id: 1}, {unique: true, drop_dups: true})
end

维持过程。

if t.training_top_records == nil
  training_top_records = TrainingTopRecord.create! training_id: t.id
else
  training_top_records = t.training_top_records
end
training_top_records.training_records = [] if training_top_records.training_records == nil
top_10_records = training_top_records.training_records
top_10_records.push({
  'id' => r.id,
  'return' => r.return
})
top_10_records.sort_by! {|record| -record['return']}
#limit training_records' size to 10
top_10_records.slice! 10, top_10_records.length - 10
training_top_records.save