to direct, how do this:
group._id = { year: { $year : [{ $subtract: [ "$timestamp", 25200000 ]}] }, month: { $month : [{ $subtract: [ "$timestamp", 25200000 ]}] }, day: { $dayofmonth : [{ $subtract: [ "$timestamp", 25200000 ]}] } };
with spring data
i tried , other forms , not successfull
aggregation aggregation = aggregation.newaggregation( aggregation.match(c), aggregation.project("programa", "custo", "duracao", "datahora") .andexpression("datahora").minus(25200000).extractdayofmonth().as("dia") .andexpression("datahora").minus(25200000).extractmonth().as("mes") .andexpression("datahora").minus(25200000).extractyear().as("ano"), aggregation.group("programa", "ano", "mes", "dia") .count().as("count") .sum("custo").as("valortotal") .sum("duracao").as("duracaototal") .first("datahora").as("datahora"), aggregation.sort(direction.asc, "datahora") );
i need group day, month , year in mongodb, or else need convert grouped data in code.
thanks in advance
you running limitation of spring mongo in can field calculations in single $project
stage, , indeed writing separate $project
since discover cannot project custom named fields directly in $group
_id
@ present either.
so better off keeping in $group
, using different method rounding adjusted dates local time.
the better way write $group
therefore be:
{ "$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" } }}
of course use sort of structure spring-mongo need custom implementation of aggregation stage operation can take defined 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); } }
which use in context this:
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") );
since custom class abstracts same basic class used built in helper methods, can used alongside them shown.
how basic process date math works here when $subtract
1 bson date object result milliseconds of difference, , in case epoch date ( date(0) ) extracts milliseconds value. allows math round current date value modulo ( $mod
) number of milliseconds in 1 day.
much tried, when $add
millisecond value bson date object returned value again bson date. adding object representing epoch returns new date object, rounded current date.
this lot more useful extracting parts via date aggregation operators, , works out bit shorter code, when adjusting time utc doing here.
though contruction of $group
here bit more terse helper functions of spring mongo trying avoid, lot more efficient in end running separate $project
stage transform field values want in $group
stage anyway.
Comments
Post a Comment