MongoTemplate:由条件子句多个字段分组

问题描述:

早些时候我有下面提到的聚合管道。MongoTemplate:由条件子句多个字段分组

db.EXCEPTIONS.aggregate(
[{ $match : { 
     $and : [ 
      {workflow_stage_current_assignee : {$ne:null}}, 
      {CreatedDate:{$gt:ISODate("2017-07-12")}}, 
      {CreatedDate:{$lt:ISODate("2018-07-12")}} 
     ]} 
}, 
{ 
    $group : {_id: {user : "$workflow_stage_current_assignee", cm:"$control_monitor"}, 
       exceptions:{$sum:1} } 
}, 
{ $project : {"user":1,"cm":1,"exceptions":1}}, 
{ $sort : {"exceptions":1}} 

]); 

Mongo模板中的相应转换如下。

Calendar fromDate = Calendar.getInstance(); 
fromDate.set(2016, 7, 12, 0, 0, 0); 

Calendar toDate = Calendar.getInstance(); 
toDate.set(2018, 7, 12, 23, 59, 59); 

MatchOperation match = Aggregation.match(new Criteria("workflow_stage_current_assignee").ne(null) 
     .andOperator(new Criteria("CreatedDate").gte(new Date(fromDate.getTimeInMillis())) 
     .andOperator(new Criteria("CreatedDate").lte(new Date(toDate.getTimeInMillis()))))); 

GroupOperation group = Aggregation.group("workflow_stage_current_assignee","control_monitor").count().as("exceptions"); 

ProjectionOperation project = Aggregation.project("workflow_stage_current_assignee","control_monitor","exceptions"); 

SortOperation sort=Aggregation.sort(Sort.Direction.DESC,"exceptions"); 

Aggregation aggregation = Aggregation.newAggregation(match,group,project,sort); 

AggregationResults<ExceptionCount> output = mongoTemplate.aggregate(aggregation, "EXCEPTIONS", ExceptionCount.class); 

这工作正常。然后我修改原来的查询,并添加额外的分组选项为逾期。

$group : {_id: {user : "$workflow_stage_current_assignee", cm:"$control_monitor"}, 
       exceptions:{$sum:1}, 
       }, 
       overdue: {$sum : {$cond :[ 
            {$gt:["$CreatedDate",ISODate("2017-07-12")]},1,0 
           ]} 
       } 

但我不知道如何在Mongo模板查询中实现这个额外的组子句。我在互联网上搜索,但大多数结果使用旧API的DBObject。有没有人可以用Mongo Template来帮助我?

+0

[如何在Spring Data MongoDB中表达复杂$ sum分组表达式]可能的副本(https://*.com/questions/46270910/how-to-express-complex-sum-grouping-expression-in-spring -data-mongodb) – Veeram

+0

我觉得我在上面的链接问题之前问过问题。所以这应该是这个问题的重复,而不是相反! :) –

+0

不知道规则是什么。该答案包括最新的更新,您可以将条件运算符作为表达式传递给sum运算符,而无需额外的项目阶段。 – Veeram

最后我找到了答案!

由于我找不到使用Mongo模板有条件地分组字段的方法,因此我必须调整聚合管道本身的逻辑。

  1. 我使用条件投影来投影额外的字段。
  2. 先执行投影操作。
  3. 然后使用这个附加字段执行分组。

因此所需的代码更改如下。

步骤1

我修改投影子句并如下加入另一个条件投影字段。

Cond overdueCondition = ConditionalOperators.when(new Criteria("CreatedDate").gt(new Date())).then(1).otherwise(0); 
ProjectionOperation project = Aggregation.project("workflow_stage_current_assignee","control_monitor","exceptions").and("overdue").applyCondition(overdueCondition); 

这种操作的结果会减少我的结果集是这样的:

{ 
"workflow_stage_current_assignee" : "Yogesh", 
"control_monitor" : "P005", 
"exceptions":"", 
"overdue" : 1 
}, 
{ 
"workflow_stage_current_assignee" : "Yogesh", 
"control_monitor" : "P005", 
"exceptions":"", 
"overdue" : 0 
}... 

执行步骤1后,我得到了在投影另一个字段名为逾期,用值1或0取决于如果我的条件满意或不满意。

步骤2

然后组子句中我用萨姆操作者添加的所有这样的逾期字段。

GroupOperation group = Aggregation.group("workflow_stage_current_assignee","control_monitor").count().as("exceptions").sum("overdue").as("overdue"); 

步骤3

最后我修改了聚合管道,然后再组所有的结果进行投影操作。

Aggregation aggregation = Aggregation.newAggregation(match,project,group,sort); 

这给了我需要的结果!