如何在mongodb中只存储一定数量的文档版本?

时间:2015-02-18 19:06:14

标签: mongodb

我们假设我想跟踪网络上的计算机,这些计算机存储有关mac-address的信息,包括设备名称,端口名称,vlan编号和时间戳。 我可以定期从所有交换机中获取mac-address-table,解析它并将该数据转储到mongodb中。

问题是:如何为每个mac-address存储最后100个唯一条目。

上限集合是不行的,因为要做到这一点,我必须为每个mac创建单独的集合,这是个坏主意。

交换机和mac地址的数量可能会随着时间的推移而变化,并且可能会以不规则的间隔插入新数据。

我的另一个想法是编写一些查询,查找每个mac-address的第100个最旧条目的时间戳,并删除所有旧条目,并在每批插入后运行此查询。它可能有用,但看起来效率不高。

你有更好的想法吗?

2 个答案:

答案 0 :(得分:2)

嗯......发现了一些有趣的东西:

如何使用$ push运算符和$ slice修饰符将每个版本存储在数组中?

文档中有一些示例: http://docs.mongodb.org/manual/reference/operator/update/slice/

答案 1 :(得分:1)

  

我的另一个想法是编写一些查询,查找每个mac-address的第100个最旧条目的时间戳,并删除所有旧条目,并在每批插入后运行此查询。它可能有用,但看起来效率不高。

这对我来说听起来不错。为此使用循环缓冲区可能更清晰:

{
   mac : "AA:AA:AA:AA:AA",
   entryPointer : 2, // pointer of the next entry to be written
   lastEntries : [
      { "ip" : "127.0.0.1", "service" : "foo", ts : ISODate(...), ... }, 
      { "ip" : "127.0.0.1", "service" : "foo", ts : ISODate(...), ... }, 
      { "ip" : "255.255.255.255", "service" : "longestProbableServiceName",
        ts : ISODate(0001-01-01), ... }
      ...
      { "ip" : "255.255.255.255", "service" : "longestProbableServiceName",
        ts : ISODate(0001-01-01), ... }
   ]
}

更新必须增加指针并覆盖指针%100给出的数组中的位置。如图所示,预先分配数组中的内存将有助于避免碎片和重新分配开销。

正如您所指出的,可以使用$slice and $push

完成模数更新
db.foo.update(
   { mac : "AA:AA:AA..." },
   {
     $push: {
       lastEntries : {
         $each: [ { "ip" : "012.002.003.012", ... } ],
         $slice: -100
       }
     }
   }
)

预先填充数组还有一个优势,即最近的条目始终位于最后一个位置。