如何将通用字段列表及其相应的第一个运算符传递给 Aggregation.group 方法

How to pass list of generic fields with their corresponding first operator to Aggregation.group method

我想使用 mongoTempalte 和 Aggregation.group() 方法编写用于聚合的通用代码。所以我遇到了使用 first() 运算符

将通用字段传递到组方法中的问题

下面是我的演示本机查询:

    db.subscriberProfile.aggregate([{"$unwind":"$usage_history"},
{ "$group" : { "_id" :"$_id" ,"birthdate" : { "$first":"$birthdate"} , "category" : { "$first":"$category"} , "control_group" : { "$first":"$control_group"}  , "sumOfTotalUsage" : { "$sum" :{"$cond": [ { "$gte" :[ "$usage_history.date" ,   ISODate( "2017-01-13T10:43:55.306Z")] }, "$usage_history.total_usage", 0]}}}},
 { "$match" : { "$and" : [ { "birthdate" : { "$lte" :  ISODate( "2017-07-12T10:43:55.306Z")}} , { "birthdate" : { "$gte" :  ISODate( "1917-07-12T10:20:35.306Z")}} , { "category" : { "$in" : [ "Prepaid"]}} , { "control_group" : false} , { "sumOfTotalUsage" : { "$gte" : 0}}]}}])

这是我在 Java 中的示例代码。

UnwindOperation unwind = Aggregation.unwind("usage_history");
GroupOperation group = Aggregation.group(fields.toArray(new String[fields.size()])).sum("usage_history.total_usage").as("sumOfTotalUsage");

我只想知道如何用$first运算符在组运算中添加多个字段。 那么,有没有办法将带有第一个运算符列表的字段列表传递给组方法。 谢谢,

试试这个代码,希望对你有帮助

UnwindOperation unwind = Aggregation.unwind("usage_history");

  BasicDBObject object = new BasicDBObject("_id", "$_id");

  for (String string : fields) {

   object.append(string, new BasicDBObject("$first", "$" + string));
  }

  object.append("total", new BasicDBObject("$sum", new BasicDBObject("$cond",
    new Object[] { new BasicDBObject("$gte", new Object[] { "$usage_history.date", calendarMin.getTime() }),
      "$usage_history.total_usage", 0 })));

  BasicDBObject groupObject = new BasicDBObject("$group", object);
  DBObject groupOperation = (DBObject) groupObject;

  MatchOperation matchMain = Aggregation
    .match(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()])));

  Aggregation aggregation = Aggregation.newAggregation(unwind, new CustomGroupOperation(groupOperation),
    matchMain);