RavenDB OrderByDescending和Take - 不正确的结果

时间:2012-01-19 18:26:05

标签: linq ravendb take

这个查询直到最近才对我有用。我现在在RavenDB中有135个InstallationSummary文档。它不是在开始时间内获得最新版本,而是主要正在工作,但最后几个,最近的文档没有显示在此查询中。我错误地查询了吗?有什么不同的方法可以使用我应该注意的OrderByDescending和Take with RavenDB吗?我可以正确查询的文件编号是否有限制?

注意:我已经调试了这个,查询确实返回了我们在网格中看到的内容。在运行查询和UI中显示的内容之间没有进行任何转换。

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 PM:

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-philosophy-discussion-with-Ayende.aspx http://codeofrob.com/archive/2010/05/12/ravendb-basic-usage-considerations.aspx

但为什么呢?我有一个Take()方法。我怎么能得到50份最近的文件?

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

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转到Query,我必须添加Where子句。

2 个答案:

答案 0 :(得分:3)

最终确定了真正的问题。

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<T>,而不是Expression<Func<T>>。它会返回IEnumerable<T>而不是IQueryable<T>

此时将语句从IQueryable<T>转换为IEnumerable<T>。这意味着RavenDB服务器只处理查询的第一部分,该部分没有过滤或排序。

其余的语句然后在内存中应用到你得到的128个项目。因此,为什么您没有看到订购或过滤的项目。

还有更多信息herehere

通常,您不必担心Func<T>Expression<Func<T>>之间的区别,编译器会为您处理它。但是如果你将自己的函数调用引入到LINQ语句中,那么你需要做到正确。

答案 1 :(得分:1)

RavenDB默认使用最终一致性,因此索引可以是s tale unless you explicitly specify otherwise

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

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