5

我正在尝试使用 mongotemplate 创建聚合查询,其中按日期(即 2016-03-01)而不是日期时间(即 2016-03-01 16:40:12)分组。该dateToString操作存在于 mongodb 文档中,它可用于使用格式从日期时间中提取日期: https : //docs.mongodb.org/manual/reference/operator/aggregation/dateToString/ 但我得到它与 mongotemplate 一起使用- 我得到一个 NullPointerException。(我的数据库版本是 3.2)

List<AggregationOperation> aggregationOperations = new ArrayList<AggregationOperation>();

aggregationOperations.add(
          Aggregation.project("blabla", ...).
          andExpression("dateToString('%Y-%m-%d',timeCreated).as("date"));

aggregationOperations.add(Aggregation.group("date").sum("blabla").as("blabla"));

AggregationResults<?> aggregationResults = this.mongoTemplate.aggregate(
                        Aggregation.newAggregation(aggregationOperations),
                                    collectionName,
                                    resultClass);

当我dayOfMonth(timeCreated)用来提取一天时,也不例外,但我找不到如何使用dateToString. 我尝试不使用 '' 作为日期格式,但它也没有工作......

这是我得到的例外:

java.lang.NullPointerException
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:226)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:194)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:255)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:194)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:255)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:194)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:255)
    at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:324)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:263)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:194)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:136)
    at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:36)
    at com.mongodb.OutMessage.putObject(OutMessage.java:289)
    at com.mongodb.OutMessage.writeQuery(OutMessage.java:211)
    at com.mongodb.OutMessage.query(OutMessage.java:86)
    at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:81)
    at com.mongodb.DB.command(DB.java:320)
    at com.mongodb.DB.command(DB.java:299)
    at com.mongodb.DB.command(DB.java:374)
    at com.mongodb.DB.command(DB.java:246)
    at org.springframework.data.mongodb.core.MongoTemplate$2.doInDB(MongoTemplate.java:357)
    at org.springframework.data.mongodb.core.MongoTemplate$2.doInDB(MongoTemplate.java:355)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:442)
    at org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:355)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1497)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1432)

编辑:

最终我们在这里决定采用不同于下面建议的解决方案,我在这里写它以防其他人发现它有用:

除了保存日期时间的“timeCreated”字段之外,我们在文档中保存了另一个字段:“date”,它只保存日期(只要)。

例如如果“timeCreated”=“2015-12-24 16:36:06.657+02:00”,那么日期是“2015-12-24 00:00:00”,我们保存1449180000000。现在我们可以简单地分组按“日期”。

4

2 回答 2

6

您可以尝试先在投影操作中使用SpELandExpression来投影字段,然后在组操作中按新字段进行分组:

Aggregation agg = newAggregation(
    project()       
        .andExpression("year(timeCreated)").as("year")
        .andExpression("month(timeCreated)").as("month")
        .andExpression("dayOfMonth(timeCreated)").as("day"),
    group(fields().and("year").and("month").and("day"))     
        .sum("blabla").as("blabla")
);

AggregationResults<BlaBlaModel> result = 
    mongoTemplate.aggregate(agg, collectionName, BlaBlaModel.class);
List<BlaBlaModel> resultList = result.getMappedResults();
于 2016-01-03T15:10:21.090 回答
1

您可以尝试使用 DateOperators.DateToString 类

aggregationOperations.add(
      Aggregation.project("blabla", ...).
      and(DateOperators.DateToString.dateOf("timeCreated").toString("%Y-%m-%d"));
于 2019-02-14T15:22:30.267 回答