在MongoDB中,获取第一个和最后一个文档的最有效方式是什么

人气:1,207 发布:2022-09-10 标签: c# linq mongodb mongodb-.net-driver

问题描述

我有这样的文档:

class A
{
    DateTime T;
    ...
}

我想查找最早和最新的文档。

这样做是否更好:

        var First   = db.Collection.AsQueryable().OrderBy(_ => _.t).FirstOrDefault();
        var Last    = db.Collection.AsQueryable().OrderByDescending(_ => _.t).FirstOrDefault();

        var First   = db.Collection.AsQueryable().OrderBy(_ => _.t).FirstOrDefault();
        var Last    = db.Collection.AsQueryable().OrderBy(_ => _.t).LastOrDefault();

        var C = db.Collection.AsQueryable().OrderBy(_ => _.t);
        var First = C.FirstOrDefault();
        var Last = C.LastOrDefault();

我想知道基础实现中是否有什么东西会更改这些选项之间的速度?

我想知道排序是否已经进行了一次,是否有可能缓存结果,获取第一个和最后一个元素会更快?

当您对驱动程序语法不确定时,

推荐答案

Profiler将成为您的朋友。要启用所有查询的日志记录,您需要在数据库上运行下面的语句:

db.setProfilingLevel(2)

然后检查您需要运行的数据库上执行的最后一个查询:

db.system.profile.find().limit(1).sort( { ts : -1 } ).pretty()

因此,对于第一个代码片段,您将获得:

"pipeline" : [ { "$sort" : { "t" : 1 }  },
               { "$limit" : 1 }
]

"pipeline" : [ { "$sort" : { "t" : -1 }  },
               { "$limit" : 1 }
]

打印第二对

"pipeline" : [ { "$sort" : { "t" : 1 }  },
               { "$limit" : 1 }
]

并在我的机器上抛出LastOrDefaultNotSupportdException,如果它在您的MongoDB驱动程序版本上运行,您可以使用探查器检查生成的MongoDB语句

当您将鼠标悬停在Visual Studio中的c上时,它会打印最后一个

{aggregate([{ "$sort" : { "t" : 1 } }])}
但是因为它的类型是IOrderedQueryable<T>,所以它只是不是物化查询,所以当您运行FirstOrDefault生成与前面语句相同的聚合体时,它将在数据库上执行。我在这里也收到了NotSupportdException。Here您可以找到受支持的LINQ运算符的列表,但LastLastOrDefault都未实现,因此您需要按降序排序。

865