在 mongodb 中,获取第一个和最后一个文档的最有效方法是什么
in mongodb, what is the most efficient way to get the first and last document
我有这样的文件:
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 }
]
并在我的机器上为 LastOrDefault
抛出 NotSupportedException,如果它适用于你的 MongoDB 驱动程序版本,你可以检查生成的 MongoDB 语句使用探查器
对于最后一个,当您将鼠标悬停在 Visual Studio 中的 c
上时,它会打印
{aggregate([{ "$sort" : { "t" : 1 } }])}
但由于它是 IOrderedQueryable<T>
类型,它只是不是具体化查询,因此当您 运行 FirstOrDefault
生成与先前语句相同的聚合主体时,它将在数据库上执行。我也在这里收到 NotSupportedException。 Here 您可以找到受支持的 LINQ 运算符列表,并且 Last
和 LastOrDefault
均未实现,因此您需要降序排序。
我有这样的文件:
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 }
]
并在我的机器上为 LastOrDefault
抛出 NotSupportedException,如果它适用于你的 MongoDB 驱动程序版本,你可以检查生成的 MongoDB 语句使用探查器
对于最后一个,当您将鼠标悬停在 Visual Studio 中的 c
上时,它会打印
{aggregate([{ "$sort" : { "t" : 1 } }])}
但由于它是 IOrderedQueryable<T>
类型,它只是不是具体化查询,因此当您 运行 FirstOrDefault
生成与先前语句相同的聚合主体时,它将在数据库上执行。我也在这里收到 NotSupportedException。 Here 您可以找到受支持的 LINQ 运算符列表,并且 Last
和 LastOrDefault
均未实现,因此您需要降序排序。