2017-08-14 1 views
1

Mongoドライババージョン:2.2.4.26C#Driver-LINQ - Aggragate - Intに含まれています

いくつかの集計を実行する次のクエリがあります。 Where句からContains述語を削除すると、クエリは正常に実行されます。

私はクライアントのメモリにデータを実現する前に、サーバで集約を減らして実行したいと思います。私が遭遇している問題は、Where句にContainsを使用すると、次の例外が発生します。

$ projectまたは$ groupはSum({document} {ForecastQuantity})をサポートしていません。好きではないドライバは(含まれてい

public class Forecast 
{ 
    public int MarkdownGroupId { get; set; } 
    public List<ForecastData> ForecastArray { get; set; } 
... 
} 

public class ForecastData 
{ 
    public int MarkdownNumber { get; set; } 
    public double ForecastQuantity { get; set; } 
... 
} 

public class Flat 
{ 
    public int MarkdownGroupId { get; set; } 
    public int MarkdownNumber { get; set; } 
    public double SalesQuantity { get; set; } 

... 
} 

public class FlatProjection 
{ 
    public int MarkdownGroupId { get; set; } 
    public int MarkdownNumber { get; set; } 
    public double SalesQuantity { get; set; } 

... 
} 

int[] groupIds = new int[]{ 1,2,3 }; 
var forecastProductDay = _mdb.GetCollection<Forecast>(collectionName); 

     var forecastProductProjections = forecastProductDay 
      .AsQueryable() 
      .Where(x => groupIds.Contains(x.MarkdownGroupId)) 
      .SelectMany(x => x.ForecastArray, (x, fa) => new Flat   
      { 
       MarkdownGroupId = x.MarkdownGroupId, 
       MarkdownNumber = fa.MarkdownNumber, 
       ForecastQuantity = fa.ForecastQuantity, 
       ... 
      }) 
      .GroupBy(key => new {key.MarkdownGroupId, key.MarkdownNumber}) 
      .Select(g => new FlatProjection 
      { 
       MarkdownGroupId = g.Key.MarkdownGroupId, 
       MarkdownNumber = g.Key.MarkdownNumber, 
       SalesQuantity = g.Sum(y => y.ForecastQuantity), 
       ... 
      }) 
      .OrderBy(x => x.MarkdownGroupId) 
      .ThenBy(x => x.MarkdownNumber) 
      .ToList(); 
+0

これはおそらくドライバのエラーです。式を 'Where(x => x.MarkdownGroupId == 1 || x.MarkdownGroupId == 2 || x.MarkdownGroupId == 3)'に変換すると動作しますか? – dasblinkenlight

+0

はい。それは動作します 場所への変換(x => x.MarkdownGroupId == 1 || x.MarkdownGroupId == 2 || x.MarkdownGroupId == 3) –

+0

あなたはリストにいくつのIDを持っていますか?おそらく、この問題を回避するためにORリストを動的に作成することができます。 – dasblinkenlight

答えて

2

ので)、または任意の():

私は、可能な場合はネイティブ対LINQの実装に滞在することを好むだろう。私はPredicateBuilderを使って動的に式を構築しました。

public static class PredicateBuilder 
{ 
    public static Expression<Func<T, bool>> True<T>() { return f => true; } 
    public static Expression<Func<T, bool>> False<T>() { return f => false; } 

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, 
                 Expression<Func<T, bool>> expr2) 
    { 
     var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); 
     return Expression.Lambda<Func<T, bool>> 
       (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); 
    } 

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, 
                 Expression<Func<T, bool>> expr2) 
    { 
     var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); 
     return Expression.Lambda<Func<T, bool>> 
       (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); 
    } 
} 

リストints =新しいリスト(){1,2,3};

 var predicate = PredicateBuilder.False<Forecast>(); 
     foreach (var i in ints) 
     { 
      predicate = predicate.Or(x => x.MarkdownGroupId == i); 
     } 

var forecastProductDay = _mdb.GetCollection(collectionName);

var forecastProductProjections = forecastProductDay 
     .AsQueryable() 
     .Where(predicate.Compile()) 
     .SelectMany(x => x.ForecastArray, (x, fa) => new Flat   
     { 
      MarkdownGroupId = x.MarkdownGroupId, 
      MarkdownNumber = fa.MarkdownNumber, 
      ForecastQuantity = fa.ForecastQuantity, 
      ... 
     }) 
     .GroupBy(key => new {key.MarkdownGroupId, key.MarkdownNumber}) 
     .Select(g => new FlatProjection 
     { 
      MarkdownGroupId = g.Key.MarkdownGroupId, 
      MarkdownNumber = g.Key.MarkdownNumber, 
      SalesQuantity = g.Sum(y => y.ForecastQuantity), 
      ... 
     }) 
     .OrderBy(x => x.MarkdownGroupId) 
     .ThenBy(x => x.MarkdownNumber) 
     .ToList(); 
関連する問題