使用RavenDB检索超过128个文档的正确方法

时间:2012-04-06 20:34:29

标签: ravendb

我知道此问题的变体之前已被问过(即使是我),但我仍然不明白这个问题......

我的理解是,通过这样做可以检索比128默认设置更多的文档:

session.Advanced.MaxNumberOfRequestsPerSession = int.MaxValue;

我已经知道WHERE子句应该是ExpressionTree而不是Func,因此它被视为Queryable而不是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);

如果我添加Take(n),那么我可以获得尽可能多的文档。例如,这将返回200个文档:

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

基于所有这些,似乎检索数千个文档的适当方法是设置MaxNumberOfRequestsPerSession并在查询中使用Take()。是对的吗?如果没有,应该如何呢?

对于我的应用,我需要检索数千个文档(其中包含非常少的数据)。我们将这些文档保存在内存中,并用作图表的数据源。

**编辑**

我尝试在Take()中使用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"
}

5 个答案:

答案 0 :(得分:36)

值得注意的是,自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 :(得分:23)

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

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

有关详细信息,请参阅:http://ravendb.net/docs/intro/safe-by-default

答案 2 :(得分:16)

Take(n)功能默认情况下最多只能提供1024个。但是,您可以与Skip(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

答案 3 :(得分:5)

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

如果您从商店获得超过10件商品(甚至低于默认值128)供人类消费,那么出现问题或者您的问题需要不同的思考,然后卡车装载来自数据存储的文件。

RavenDB索引非常复杂。关于索引here和facets 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)();

答案 4 :(得分: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()。