2016-01-03 1 views
2

Я пытаюсь создать совокупный запрос, используя mongotemplate, где есть группировка по дате (т.е. 2016-03-01) вместо datetime (т.е. 2016-03-01 16:40:12) , Операция dateToString существует в документации mongodb, ее можно использовать для извлечения даты из datetime с помощью форматирования: https://docs.mongodb.org/manual/reference/operator/aggregation/dateToString/ , но я получаю его для работы с mongotemplate - я получаю исключение NullPointerException. (моя дб версия 3,2)MongoTemplate aggregate - group by date

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) 

EDIT:

В конце концов мы решили здесь на другом решении, чем то, что было предложено ниже, я пишу его здесь, если кто-либо найдет это полезным:

В дополнение к полю «timeCreated», которое содержит дату и время, мы сохранили другое поле в документе: дата ", tha t имеет только дату (так долго).

Например, если «timeCreated» = «2015-12-24 16: 36: 06.657 + 02: 00», то дата «2015-12-24 00:00:00», и мы сохраняем 1449180000000. Теперь мы можем просто сгруппировать по «дате».

ответ

1

Вы можете попробовать проецирование полех первым с помощью SpEL andExpression в операции проекции, а затем группу по новым направлениям в работе группы:

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(); 
+0

Спасибо, я мог бы сделать это, но мне кажется, гораздо проще использовать dateToString, за исключением того, что я не знаю, почему это порождает исключение ... – Ayelet

+1

@Ayelet Я боюсь Spring Data MongoDB в настоящее время не поддерживает это, есть открытый JIRA билет для этого специально [здесь] (https : //jira.spring.io/browse/DATAMONGO-1299) – chridam

+1

это очень плохо :(но спасибо в любом случае – Ayelet