如何将MongoDB用作唯一/枚举存储

时间:2012-07-06 09:33:44

标签: c# mongodb enumeration bigdata

这似乎是一个常见的用例...但不知怎的,我无法让它发挥作用。

我正在尝试将MongoDB用作具有唯一项目的枚举存储。我创建了一个带有byte [] Id(唯一ID)和时间戳(长,用于枚举)的集合。该商店相当大(太字节)并分布在不同的服务器之间。我现在能够从头开始重新建立商店,因为我还处于测试阶段。

我想做的是两件事:

  1. 为我插入的每个项目创建唯一ID。这基本上意味着如果我插入两次相同的ID,MongoDB将检测到这一点并给出错误。这种方法似乎工作正常。
  2. 通过其他进程连续枚举新商品的商店。我采用的方法是向InsertID添加第二个索引,并在其上使用高精度时间戳以及服务器ID和计数器(只是为了使其唯一且升序)。
  3. 在最佳方案中,这意味着枚举器将跟踪每个服务器的索引游标。从我从mongodb查询处理中学到的东西,我预计会出现这种情况。但是,当我尝试执行代码(下面)时,似乎需要永远得到任何东西。

            long lastid = 0;
            while (true)
            {
                DateTime first = DateTime.UtcNow;
                foreach (var item in collection.FindAllAs<ContentItem>().OrderBy((a)=>(a.InsertId)).Take(100))
                {
                    lastid = item.InsertId;
                }
                Console.WriteLine("Took {0:0.00} for 100", (DateTime.UtcNow - first).TotalSeconds);
            }
    

    我已经阅读了游标,但我不确定它们是否满足新商品插入商店时的要求。

    正如我所说,我不会受任何表结构或类似的东西......唯一重要的事情是我可以随着时间的推移获得新的项目而不会得到重复的项目。

    -Stefan。

1 个答案:

答案 0 :(得分:0)

不知怎的,我想出来......或多或少......

我手动创建了查询,结果是这样的:

  

db.documents.find({“InsertId”:{“$ gt”:NumberLong(“2020374866209304106”)}})。limit(10).sort({“InsertId”:1});

我在问题中提出的LINQ查询不会生成此查询。经过一些挖掘代码后,我发现它应该是这个LINQ查询:

  

foreach(collection.AsQueryable()中的var项。其中((a)=&gt;(a.InsertId&gt; lastid))。OrderBy((a)=&gt;(a.InsertId))。Take(100 ))

AsQueryable()似乎是执行LINQ to MongoDB查询重写的关键。

这给出了结果,但它们看起来仍然很慢(10个结果为4秒,100个为30个)。但是,当我添加'explain()'时,我在查询执行中注意到'0 millis'。

我停止了批量插入和tada的过程,它工作正常,而且速度很快。换句话说:我遇到的问题是由于MongoDB的锁定行为,以及由于我解释linq实现的方式。由于前者是初始批量填充数据存储的结果,这意味着问题得以解决。

在解决方案的“否定”部分:我更倾向于使用可序列化游标或其他类似的解决方案...这个'take'解决方案必须一遍又一遍地迭代b-tree。如果有人对此有答案,请告诉我。

-Stefan。