我有一个mongo集合,大约有600k文档。我正在枚举该集合,按_id排序。但是,文档不会按该排序顺序返回。它们似乎根据ObjectId的时间戳部分正确排序,但不是根据pid字段排序。
这是我用来重现的c#代码:
var cursor = m_collection.FindAll().SetSortOrder(SortBy.Ascending("_id"));
ObjectId previous = ObjectId.Empty;
foreach (var document in cursor)
{
var id = document[IdField].AsObjectId;
Throw.Assert(id > previous, "Sort order is invalid!");
previous = id;
}
在某些时候,断言被触发。我可以看到新id与前一个id具有相同的时间戳,但是pid较低。
我原本以为使用{“_ id”:1}进行排序会使用ObjectIds的所有组件进行排序,而不仅仅是时间戳。
服务器是否使用与C#客户端的ObjectId.CompareTo不同的ObjectIds比较算法?
答案 0 :(得分:0)
MongoDB C#CompareTo
的来源目前为here。代码将ObjectId
的每个元素一直比较为3字节计数器。鉴于包含ObjectId的性质:
超出时间戳排序是没有意义的。 CompareTo
虽然准确并且会产生一致的结果,但可能不会以符合您期望的方式排序。
假设存在两个对象在同一时间戳(4字节值)创建的情况,那么在给定C#中CompareTo
的方式的情况下,结果会有一些差异。因此,执行断言会导致一些令人困惑的结果,不应该用作检测序列结果的方法。
大多数驱动程序在不存在时创建_id
/ ObjectId
值(包括C#驱动程序)。除了时间戳之外,你真的没什么可以排序的。
你可以这样做:
Throw.Assert(id.Timestamp > previous.Timestamp, "Sort order is invalid!");