您在单一
$project阶段可以进行字段计算时遇到了Spring
mongo的局限性,并且实际上您可能已经单独编写了,
$project因为您发现目前也不能直接在项目中自定义命名字段。
$group
_id
因此,最好将所有内容都保留在中
$group,并使用其他方法将调整后的日期四舍五入为当地时间。
因此,更好的写方法
$group是:
{ "$group": { "_id": { "programa": "$programa", "dataHora": { "$add": [ { "$subtract": [ { "$subtract": [{ "$subtract": ["$dataHora", new Date(0)] }, 25200000 ] }, { "$mod": [ { "$subtract": [{ "$subtract": ["$dataHora", new Date(0)] }, 25200000 ] }, 1000 * 60 * 60 * 24 ]} ]}, new Date(0) ] } }, "count": { "$sum": 1 }, "valorTotal": { "$sum": "$custo" }, "duracaoTotal": { "$sum": "$duracao" }, "dataHora": { "$first": "$dataHora" }}}
当然,要将这种结构与spring-mongo结合使用,您需要一个聚合阶段 *** 作的自定义实现,该实现可以采用定义
DBObject:
public class CustomGroupOperation implements AggregationOperation { private DBObject operation; public CustomGroupOperation (DBObject operation) { this.operation = operation; } @Override public DBObject toDBObject(AggregationOperationContext context) { return context.getMappedObject(operation); }}
然后在如下上下文中使用它:
Aggregation aggregation = Aggregation.newAggregation( Aggregation.match(c), new CustomGroupOperation( new BasicDBObject("$group", new BasicDBObject("_id", new BasicDBObject("programa","$programa") .append("dataHora", new BasicDBObject("$add",Arrays.asList( new BasicDBObject("$subtract",Arrays.asList( new BasicDBObject("$subtract",Arrays.asList(new BasicDBObject("$subtract",Arrays.asList( "$dataHora", new Date(0))),25200000 )), new BasicDBObject("$mod",Arrays.asList(new BasicDBObject("$subtract",Arrays.asList( new BasicDBObject("$subtract",Arrays.asList( "$dataHora", new Date(0) )), 25200000)),1000 * 60 * 60 * 24 )) )), new Date(0) )) ) ) .append("count",new BasicDBObject("$sum",1)) .append("valorTotal",new BasicDBObject("$sum","$custo")) .append("duracaoTotal",new BasicDBObject("$sum","$duracao")) .append("dataHora",new BasicDBObject("$first","$dataHora")) ) ), Aggregation.sort(Direction.ASC,"_id.dataHora") );
由于定制类是从内置辅助方法使用的同一基本类中抽象出来的,因此可以如图所示将其与它们一起使用。
日期数学的基本过程在这里是如何工作的,当您将
$subtract另一个BSON
Date对象与另一个对象进行比较时,结果是相差的毫秒数,在这种情况下,是从纪元日期(Date(0))提取出来的毫秒数。这使您可以进行数学运算,以
$mod一天中的毫秒数乘以模()来舍入到当前日期值。
就像您最初尝试过的那样,当您然后
$add将该BSON
Date对象的毫秒值返回时,返回的值再次是BSON Date。因此,添加到表示纪元的对象将返回一个新的Date对象,但四舍五入到当前日期。
这通常比通过日期聚合运算符提取零件有用得多,并且计算出来的代码要短一些,尤其是在调整此处从UTC的时间时。
尽管
$group这里的结构比Spring
mongo的帮助函数要避免的简洁得多,但最终它比运行一个单独的
$project阶段来转换您仅在该
$group阶段真正想要的字段值要有效得多无论如何。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)