C# Driver- LINQ - Aggragate - Contains in Int[] -
mongo driver version: 2.2.4.26
i have following query performs aggregations. if remove contains predicate clause, query executes successfully.
i reduce , perform aggregation on server before realizing data client memory. issue encountering when use contains in clause, following exception:
$project or $group not support sum({document}{forecastquantity}).
i prefer stay in linq implementation vs. native if possible:
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();
since driver not contains() or any(). had build expression dynamically using 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); } }
list ints = new list() {1,2,3};
var predicate = predicatebuilder.false<forecast>(); foreach (var 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();
Comments
Post a Comment