2012-04-06 74 views
26

我知道这个问题的变种之前(甚至我)已经被问过,但我还是不明白,一两件事这个...正确的方法来检索超过128个文件与RavenDB

它我的理解是一个可以通过这样检索比128的默认设置的详细资料:

session.Advanced.MaxNumberOfRequestsPerSession = int.MaxValue; 

而且我了解到,WHERE子句应该是一个ExpressionTree而不是Func键,以便它是作为可查询的,而不是治疗Enumerable的。所以我认为这应该工作:

public static List<T> GetObjectList<T>(Expression<Func<T, bool>> whereClause) 
{ 
    using (IDocumentSession session = GetRavenSession()) 
    { 
     return session.Query<T>().Where(whereClause).ToList();     
    } 
} 

但是,那只返回128个文件。为什么?

注意,这里是调用上述方法的代码:

RavenDataAccessComponent.GetObjectList<Ccm>(x => x.TimeStamp > lastReadTime); 

如果我加拿(N),那么我可以,因为我喜欢获得尽可能多的文件。例如,这将返回200个文件:基于这一切

return session.Query<T>().Where(whereClause).Take(200).ToList(); 

,它似乎是检索数以千计的文件进行适当的方法是设置MaxNumberOfRequestsPerSession并在查询中使用采取()。是对的吗?如果不是,应该如何做

对于我的应用程序,我需要检索数千份文件(即在他们的数据非常少)。我们将这些文档保存在内存中,并用作图表的数据源。

**编辑**

我在采取()使用int.MaxValue尝试:

return session.Query<T>().Where(whereClause).Take(int.MaxValue).ToList(); 

并返回1024哎呀。我如何获得超过1024个?

**编辑2 - 样品文件显示数据**

{ 
    "Header_ID": 3525880, 
    "Sub_ID": "120403261139", 
    "TimeStamp": "2012-04-05T15:14:13.9870000", 
    "Equipment_ID": "PBG11A-CCM", 
    "AverageAbsorber1": "284.451", 
    "AverageAbsorber2": "108.442", 
    "AverageAbsorber3": "886.523", 
    "AverageAbsorber4": "176.773" 
} 
+0

您是否想过将一个文档中的所有10000个点作为一个集合? – SteadyEddi 2012-05-26 18:28:46

回答

20

Take(n)功能只会给你最多1024默认情况下。但是,您可以在Raven.Server.exe.config更改此默认:

<add key="Raven/MaxPageSize" value="5000"/> 

欲了解更多信息,请参见:http://ravendb.net/docs/intro/safe-by-default

+0

谢谢,迈克。我认为这将最终成为被接受的答案,但我想先看看其他人是否有不同的观点。 – 2012-04-07 01:00:52

5

每个会话的请求数是一个独立的概念,然后每次通话检索的文档数量。会议短暂,预计只有很少的电话发出。

如果您是从商店(甚至小于默认128)供人食用获得超过10的东西那么什么是错的还是你的问题是需要不同的思维,然后从数据存储文件来卡车装载。

RavenDB索引是相当复杂的。关于索引here和方面here的好文章。

如果你有需要进行数据汇总,创建的map/reduce指数,这导致聚合数据例如:

指数:

from post in docs.Posts 
    select new { post.Author, Count = 1 } 

    from result in results 
    group result by result.Author into g 
    select new 
    { 
     Author = g.Key, 
     Count = g.Sum(x=>x.Count) 
    } 

查询:

session.Query<AuthorPostStats>("Posts/ByUser/Count")(x=>x.Author)(); 
+1

那么你会如何解决这个问题?该公司希望看到一张图表,显示最近24小时的数据点。每个文件都是一个数据点,过去24小时内有10,000个文件。如何在没有提供所有数据的情况下绘制图表? – 2012-04-07 01:03:08

+0

我认为你可以通过创建索引或[方面](http://ravendb.net/docs/client-api/faceted-search) – 2012-04-07 01:08:12

+0

来实现这一点我刚刚注意到“每个文档都是一个数据点” - 你能显示这个文件的一个例子? – 2012-04-07 01:34:33

16

取(n)函数将默认情况下只给你高达1024。但是,您可以在对使用它跳过(N)来获取所有

 var points = new List<T>(); 
     var nextGroupOfPoints = new List<T>(); 
     const int ElementTakeCount = 1024; 
     int i = 0; 
     int skipResults = 0; 

     do 
     { 
      nextGroupOfPoints = session.Query<T>().Statistics(out stats).Where(whereClause).Skip(i * ElementTakeCount + skipResults).Take(ElementTakeCount).ToList(); 
      i++; 
      skipResults += stats.SkippedResults; 

      points = points.Concat(nextGroupOfPoints).ToList(); 
     } 
     while (nextGroupOfPoints.Count == ElementTakeCount); 

     return points; 

RavenDB Paging

+1

这种方法是迄今为止更好的方法。 – Matt 2013-05-09 16:03:40

+4

请注意服务器请求数量的限制。根据Raven的“默认安全”设置,它只能达到服务器的30次往返,因此如果循环需要执行的次数超过了这个次数,它将会失败,因为循环的每次迭代都是另一个服务器请求。 – 2014-02-12 18:47:13

34

值得注意的是,自从2.5版本,RavenDB有一个“无界成果API”允许流。从文档的例子显示了如何使用此:

var query = session.Query<User>("Users/ByActive").Where(x => x.Active); 
using (var enumerator = session.Advanced.Stream(query)) 
{ 
    while (enumerator.MoveNext()) 
    { 
     User activeUser = enumerator.Current.Document; 
    } 
} 

有标准RavenDB查询,查询Lucence支持,也有异步支持。

该文档可以找到here。 Ayende的介绍性博客文章可以在here找到。

+1

提示+1。谢谢! – 2013-11-27 13:59:41

+3

请注意,使用Streaming API查询时,索引必须已经存在。如果您通过普通会话API运行查询,并且不存在匹配的索引,则会创建一个动态索引。但是在流媒体API中,动态索引未创建,服务器抱怨索引未找到。 – 2014-02-12 18:42:21

+0

迈克 - 这是有趣的行为,这听起来像一个错误。你有没有在RavenDB小组中讨论过这个问题? – 2014-02-14 07:41:50

0

您也可以使用Stream方法的预定义索引。您可以在索引字段上使用Where子句。

var query = session.Query<User, MyUserIndex>(); 
var query = session.Query<User, MyUserIndex>().Where(x => !x.IsDeleted); 

using (var enumerator = session.Advanced.Stream<User>(query)) 
{ 
    while (enumerator.MoveNext()) 
    { 
     var user = enumerator.Current.Document; 
     // do something 
    } 
} 

例指数:

public class MyUserIndex: AbstractIndexCreationTask<User> 
{ 
    public MyUserIndex() 
    { 
     this.Map = users => 
      from u in users 
      select new 
      { 
       u.IsDeleted, 
       u.Username, 
      }; 
    } 
} 

文档:What are indexes? Session : Querying : How to stream query results?


重要提示:Stream方法不会跟踪对象。如果您更改从此方法获得的对象,SaveChanges()将不会意识到任何更改。


其他注意事项:如果您未指定要使用的索引,则可能会遇到以下异常。

InvalidOperationException:StreamQuery不支持查询动态索引。它被设计为与大型数据集一起使用,并且不太可能在索引15秒后返回所有数据集,例如Query()。

相关问题