关于linq:RavenDB OrderByDescending和Take – 不正确的结果

RavenDB OrderByDescending and Take - Incorrect Results

直到最近,这个问题一直对我有效。我的RavenDB中现在有135个安装摘要文档。它不是按开始时间获取最新的文档,而是主要工作的,但是最后两个文档,从这个查询中不会显示最新的文档。我是否查询错误?有没有不同的方法来执行orderbyDescending和take with ravendb,我应该知道?对于我可以正确查询的内容,是否有文档编号限制?

注意:我已经对此进行了调试,查询实际上返回了我们在网格中看到的内容。在运行查询的时间和用户界面中显示的时间之间没有进行转换。

1
2
3
4
5
6
7
IEnumerable<InstallationSummary> installationSummaries =
  QueryAndCacheEtags(session => session.Advanced.LuceneQuery<InstallationSummary>()
  .Include(x => x.ApplicationServerId)
  .Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
  .Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)
  .OrderByDescending(summary => summary.InstallationStart)
  .Take(numberToRetrieve)).Cast<InstallationSummary>().ToList();

此网格应显示更多行,开始时间大于1/19/2012下午6:33:51:

enter image description here

编辑:我从查询中删除了take(numbertoretrieve),总共160个installationsummary文档中只有128个。我可以在RavenDB Studio中看到所有160个,但从查询中只返回128个。128…128…2的力量…我达到极限了吗?

好吧,看起来我达到了128的极限:http://www.blogcoward.com/archive/2010/05/21/ravendb-and-a-brief-design-physical-discussion-with-ayende.aspxhttp://codeofrob.com/archive/2010/05/12/ravendb-basic-usage-considerations.aspx

但是为什么呢?我有一个take()方法。我怎样才能拿到50份最新的文件?

作为一个小小的黑客,下面的查询至少会显示最新的。这并不是我想要的,因为我想要最近的50个,不管日期如何。只要自开始日期起不超过50个,这至少会显示最近的项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
using Raven.Client.Linq;

DateTime startDate = new DateTime(2012, 1, 18);

IEnumerable<InstallationSummary> installationSummaries =
QueryAndCacheEtags(session => session.Query<InstallationSummary>()
.Include(x => x.ApplicationServerId)
.Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
.Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)                        
.Where(x => x.InstallationStart > startDate)
.OrderByDescending(summary => summary.InstallationStart)                        
.Take(numberToRetrieve)
).Cast<InstallationSummary>().ToList();

我必须从LuceneQuery转到JustQuery,并且必须添加WHERE子句。


终于解决了真正的问题。

1
2
3
4
5
6
7
8
9
10
IEnumerable<InstallationSummary> installationSummaries =
    QueryAndCacheEtags(session => session.Query<InstallationSummary>()
       .Include(x => x.ApplicationServerId)
       .Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
       .Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)                        
       .Where(x => x.InstallationStart > startDate)
       .OrderByDescending(summary => summary.InstallationStart)                        
       .Take(numberToRetrieve))
       .Cast<InstallationSummary>()
       .ToList();

queryandcacheetags(..)函数的签名是Func,而不是Expression>。它返回IEnumerable而不是IQueryable

这将把当时的声明从IQueryable转换为IEnumerable。这意味着RavenDB服务器只处理查询的第一部分,没有过滤或排序。

其余的语句,然后在内存中应用到返回的128个项。因此,为什么您看不到正确订购或过滤的项目。

这里还有更多的信息

一般来说,您不必担心FuncExpression>之间的区别,编译器会为您处理它。但是,如果您将自己的函数调用引入到LINQ语句中,那么您确实需要正确地执行它。


ravendb默认使用最终的一致性,因此除非您明确指定,否则索引可能会过时。

将下面的行(或其中一个变量)添加到您的查询中:

1
  .Customize(x => x.WaitForNonStaleResultsAsOfNow())