微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 聚合项目组通过Spring Data提取日,月和年

要直接,我该怎么做:

group._id = { 
    year: { $year : [{ $subtract: [ "$timestamp", 25200000 ]}] }, 
    month: { $month : [{ $subtract: [ "$timestamp", 25200000 ]}] }, 
    day: { $dayOfMonth : [{ $subtract: [ "$timestamp", 25200000 ]}] }
};

用spring数据

我已经尝试了这个和其他一些形式并没有成功

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

我需要在mongodb中按天,月和年进行分组,否则我需要在代码中转换所有这些分组数据.

提前致谢

解决方法:

你在单个$project阶段的字段计算中遇到了弹簧mongo的限制,实际上你可能已经写了一个单独的$项目,因为你发现你不能直接在$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")
    );

由于自定义类是从内置辅助方法使用的相同基本类中抽象出来的,因此它可以与它们一起使用,如图所示.

日期数学的基本过程如何在这里工作,当你从另一个BS00 Date对象$subtract时,结果是毫秒的差异,在这种情况下从纪元日期(Date(0))中提取毫秒值.这允许您通过模数($mod)从一天中的毫秒数开始舍入到当前日期值.

就像你最初尝试的那样,当你在$add那个毫秒值到BSON Date对象时,返回的值又是BSON Date.因此,添加到表示纪元的对象会返回一个新的日期对象,但会四舍五入到当前日期.

这通常比通过date aggregation operators提取部件更有用,而且编码也有点短,特别是在调整UTC的时间时,就像在这里一样.

虽然这里的$group的构造比spring mongo的helper函数试图避免的要简单一些,但最终它比运行一个单独的$project阶段来转换字段值更有效率.无论如何都想在$group阶段.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐