首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在单个字段上创建一个对象作为GroupOperation id的Spring Data MongoDB GroupOperation?

如何在单个字段上创建一个对象作为GroupOperation id的Spring Data MongoDB GroupOperation?
EN

Stack Overflow用户
提问于 2020-08-03 21:15:40
回答 1查看 99关注 0票数 1

这是我想要根据一个命名对象创建的group操作。

代码语言:javascript
复制
private static GroupOperation createStatsGroupOperationFromNomenclature(Nomenclature nomenclature) {
    Fields groupFields = Fields.fields("departmentCode");
    nomenclature.getDepartmentCode().ifPresent(code -> groupFields.and("subDepartmentCode"));
    nomenclature.getSubDepartmentCode().ifPresent(code -> groupFields.and("categoryCode"));
    nomenclature.getCategoryCode().ifPresent(code -> groupFields.and("subCategoryCode"));
    return group(groupFields)
        .count().as("nbProducts")
        .sum("$proposedMatchesAmount").as("nbProposedMatches")
        .sum("$reviewedMatchesAmount").as("nbReviewedMatches");
}

对于前面的函数,如果我在departmentCode参数中提供了一个subDepartmentCode和一个mongo,下面是要执行的mongo查询:

代码语言:javascript
复制
{
  _id: {
    "departmentCode": "$departmentCode",
    "subDepartmentCode": "$subDepartmentCode"
  },
  "nbProduct": {
    $sum: 1
  },
  "proposedMatchesAmount": {
    $sum: "$proposedMatchesAmount"
  },
  "reviewedMatchesAmount": {
    $sum: "$reviewedMatchesAmount"
  }
}

此查询的结果将在以下对象中解析:

代码语言:javascript
复制
@Builder
@Value
public class ProductsStatsDocument {
  @Id
  Nomenclature nomenclature;
  Integer nbProducts;
  Integer nbProposedMatches;
  Integer nbReviewedMatches;
}

当我仅在departmentCode参数中提供命名时,问题就会被追加。然后,构建的组操作具有以下mongo查询语言的等价物:

代码语言:javascript
复制
{
  _id: "$departmentCode",
  "nbProduct": {
    $sum: 1
  },
  "proposedMatchesAmount": {
    $sum: "$proposedMatchesAmount"
  },
  "reviewedMatchesAmount": {
    $sum: "$reviewedMatchesAmount"
  }
}

并且这个查询的结果不能被解析成前一个ProductsStatsDocument,因为结果_id字段id现在是一个字符串,而不是一个命名对象。

即使只有一个字段,也可以强制group方法使用一个对象作为结果_id字段吗?或者,有没有其他方法来构建这样的mongo群组操作?

=================================================================

找到这个问题的“原因”。下面是spring data中的一段代码,它将GroupOperation转换为bson对象:

代码语言:javascript
复制
    } else if (this.idFields.exposesSingleNonSyntheticFieldOnly()) {
      FieldReference reference = context.getReference((Field)this.idFields.iterator().next());
      operationObject.put("_id", reference.toString());
    } else {

下面是exposesSingleNonSyntheticFieldOnly方法:

代码语言:javascript
复制
  boolean exposesSingleNonSyntheticFieldOnly() {
    return this.originalFields.size() == 1;
  }

正如您所看到的,只要只有一个字段可以分组,它就被用作_id结果值。

EN

回答 1

Stack Overflow用户

发布于 2020-08-04 18:11:32

最后,目前可行的解决方案是创建一个管理文档转换_id部件的自定义AggregationOperation:

代码语言:javascript
复制
public class ProductsStatsGroupOperation implements AggregationOperation {

  private static GroupOperation getBaseGroupOperation() {
    return group()
        .count().as("nbProducts")
        .sum("$proposedMatchesAmount").as("nbProposedMatches")
        .sum("$reviewedMatchesAmount").as("nbReviewedMatches");
  }

  private final Nomenclature nomenclature;

  public ProductsStatsGroupOperation(Nomenclature nomenclature) {
    this.nomenclature = nomenclature;
  }

  @Override
  public Document toDocument(AggregationOperationContext context) {
    Document groupOperation = getBaseGroupOperation().toDocument(context);

    Document operationId = new Document();
    for (Field field : getFieldsToGroupOn()) {
      FieldReference reference = context.getReference(field);
      operationId.put(field.getName(), reference.toString());
    }
    ((Document)groupOperation.get("$group")).put("_id", operationId);

    return groupOperation;
  }

  private Fields getFieldsToGroupOn() {
    Fields groupFields = Fields.fields("departmentCode");
    if (nomenclature.getDepartmentCode().isPresent()) {
      groupFields = groupFields.and("subDepartmentCode");
    }
    if (nomenclature.getSubDepartmentCode().isPresent()) {
      groupFields = groupFields.and("categoryCode");
    }
    if (nomenclature.getCategoryCode().isPresent()) {
      groupFields = groupFields.and("subCategoryCode");
    }
    return groupFields;
  }
}

这个解决方案有一个不好的地方:被覆盖的方法toDocument似乎已被弃用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63230160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档