何时在 RavenDB 中评估 groupby 查询? [英] When is a groupby query evaluated in RavenDB?

查看:56
本文介绍了何时在 RavenDB 中评估 groupby 查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力解决使用 RavenDB 和 LuceneQuery 进行分组的行为.

I'm struggling with the behaviour of grouping using RavenDB and LuceneQuery.

我一直觉得IEnumerable只在调用ToArray()等时被评估

I was always under the impression that IEnumerable was only evaluated when calling ToArray(), etc.

为了清楚起见,以下查询分为两部分.

The following query was split into two parts for the sake of clarity.

我不希望在对 totalledBalanceList 调用 ToArray() 之前对查询进行评估,我的期望是在服务器上对所有数据进行分组.但是,实际结果取决于 .Take() 中规定的项数.如果没有 Take(1024),则返回默认 128 个项目的结果.

I would not expect the query to be evaluated until after ToArray() is called on totalledBalanceList, my expectation being that the grouping is done on the server across all of the data. However, the actual result depends on the number of items stipulated in .Take(). Without the Take(1024), the results come back for the default 128 items.

我需要能够对整个数据集进行分组.

I need to be able to perform the grouping across the entire dataset.

using (var session = MvcApplication.RavenSession)
{
    var computedBalanceList =
        from c in session.Advanced.LuceneQuery<Journal, Ledger_ByDateAndDebitIdAndCreditIdAndValues>()
        .Where(parameters)
        .OrderBy(c => c.DateAsString).Take(1024)
        select new LedgerBalanceDto
        {
            Account = account,
            Name = queryName,
            Debits = c.DebitId == account.Id
                         ? c.DebitValue
                         : 0,
            Credits = (c.CreditId == account.Id)
                          ? c.CreditValue
                          : 0,
            Currency = (c.DebitId == account.Id) ? c.DebitCurrency : c.CreditCurrency,
            CurrencySymbol = (c.DebitId == account.Id) ? c.DebitCurrencySymbol : c.CreditCurrencySymbol,
        };

    var totalledBalanceList =
        from balance in computedBalanceList
        group new {balance.Debits, balance.Credits} by new {balance.Currency, balance.CurrencySymbol}
        into grouping
        select new LedgerBalanceDto
        {
            Account = account,
            Currency = grouping.Key.Currency,
            CurrencySymbol = grouping.Key.CurrencySymbol,
            Debits = grouping.Sum(c => c.Debits),
            Credits = grouping.Sum(c => c.Credits),
            Name = queryName
        };

    return totalledBalanceList;

和索引:

public class Ledger_ByDateAndDebitIdAndCreditIdAndValues:AbstractIndexCreationTask<Journal>
{
    public Ledger_ByDateAndDebitIdAndCreditIdAndValues()
    {
        Map = journals => from c in journals
                          select new {c.Date,c.DateAsString, c.DebitId, c.CreditId,c.DebitValue,c.CreditValue};

        Index(x=>x.Date,FieldIndexing.Analyzed);
        Index(x=>x.DateAsString,FieldIndexing.Analyzed);
        Index(x=>x.DebitId,FieldIndexing.Analyzed);
        Index(x=>x.CreditId,FieldIndexing.Analyzed);

        Index(x=>x.DebitValue,FieldIndexing.Analyzed);
        Index(x=>x.CreditValue,FieldIndexing.Analyzed);

        Sort(x=>x.DateAsString,SortOptions.String);
    }
}

我还重写了查询,以便分组发生在过滤器外部",但我得到了完全相同的结果,即结果取决于 Take().

I've also rewritten the query so that the grouping happens "outside" the filter, but I get exactly the same results, namely the result depends on the Take().

var totalledBalanceList = from balance in
    from c in query
        .Where(parameters)
        .OrderBy(c => c.DateAsString)
    select new LedgerBalanceDto
    {
        Account = account,
        Name = queryName,
        Debits = c.DebitId == account.Id
                     ? c.DebitValue
                     : 0,
        Credits = (c.CreditId == account.Id)
                      ? c.CreditValue
                      : 0,
        Currency = (c.DebitId == account.Id) ? c.DebitCurrency : c.CreditCurrency,
        CurrencySymbol = (c.DebitId == account.Id) ? c.DebitCurrencySymbol : c.CreditCurrencySymbol,
    }
    group new {balance.Debits, balance.Credits} by new {balance.Currency, balance.CurrencySymbol}
    into grouping
    select new LedgerBalanceDto
    {
        Account = account,
        Currency = grouping.Key.Currency,
        CurrencySymbol = grouping.Key.CurrencySymbol,
        Debits = grouping.Sum(c => c.Debits),
        Credits = grouping.Sum(c => c.Credits),
        Name = queryName
    };
return totalledBalanceList;

对此的任何想法将不胜感激.

Any thoughts on this would be much appreciated.

日记类的一部分:

public class Journal
{
    public string Id { get; set; }
    public string DebitId{get;set;}
    public string CreditId{get;set;}
    public decimal? ExchangeRate { get; set; }
    public decimal CreditValue {get;set;}
    public decimal DebitValue {get;set;}
    public string DebitCurrency {get;set;}
    public string CreditCurrency {get;set;}
    public decimal Nett
    {
        get { return _nett; }
        set
        {
            _nett = value;

            CreditValue = Math.Round(Nett, 2);
            DebitValue = Math.Round(Nett * (ExchangeRate ?? 1), 2);
        }
    }
   etc ...
}

示例数据 IEnumerable>:

Example data IEnumerable<Journal>:

Id     DebitId       CreditId      Nett     ExchangeRate     DbCurr     CrCurr   DbVal    CrVal

1      Expense1      Bank          100      2.03             BRL        USD      203.00   100.00
2      Expense2      Bank          50       null             USD        USD      50.00     50.00
3      Bank          Client1       300      null             USD        USD      300.00   300.00
4      Stock         Bank          300      null             USD        USD      300.00   300.00

例如,当我查询银行时,我希望能够将 DbVal 和 CrVal 相加并计算余额,但为此,我必须将其中一个或另一个归零(根据查询).

For example, when I query for the Bank, I want to be able to sum the DbVal and CrVal and calculate the balance, but in order to do so, I have to zero either one or the other (as per the query).

推荐答案

您正在混合 LINQ和 Lucene 查询,这意味着它们将在客户端上进行评估.

You are mixing LINQ and Lucene query here, and that means they will be evaluated on the client.

您需要使用 session.Query 而不是 session.Advanced.LuceneQuery 将很多内容移动到索引和查询中.

You need to move a lot of this into an index and query that using session.Query, not session.Advanced.LuceneQuery.

这篇关于何时在 RavenDB 中评估 groupby 查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆