何时在RavenDB中评估groupby查询?

时间:2012-08-15 03:33:02

标签: ravendb

我正在努力使用RavenDB和LuceneQuery进行分组行为。

我总是认为只有在调用ToArray()等时才会评估IEnumerable。

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

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

我需要能够在整个数据集中执行分组。

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);
    }
}

我还重写了查询,以便分组发生在&#34;外面&#34;过滤器,但我得到完全相同的结果,即结果取决于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;

对此的任何想法都将非常感激。

期刊课程的一部分:

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 <Journal&gt;:

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求和并计算余额,但为了做到这一点,我必须将其中一个归零(根据查询) )。

1 个答案:

答案 0 :(得分:0)

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

您需要将大量此操作转移到使用session.Query的索引和查询中,而不是session.Advanced.LuceneQuery。