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

时间:2019-06-29 23:35:06

标签: c# mongodb linq 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();

我想知道底层实现是否会改变这些选项之间的速度?

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

1 个答案:

答案 0 :(得分:2)

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

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 }
]

并在我的计算机上为LastOrDefault抛出 NotSupportedException ,如果它适用于MongoDB驱动程序的版本,则可以使用探查器检查生成的MongoDB语句

在您将鼠标悬停在Visual Studio中的c上时,它会打印

{aggregate([{ "$sort" : { "t" : 1 } }])}

,但是由于它的类型为IOrderedQueryable<T>,因此它不是唯一的查询,因此当您运行FirstOrDefault并生成与先前语句相同的聚合主体时,它将在数据库上执行。我也在这里收到NotSupportedException。 Here可以找到受支持的LINQ运算符的列表,并且LastLastOrDefault均未实现,因此您需要对降序进行排序。