为什么 MongoDB 聚合被 Spring 数据以错误的方式重写?

Why MongoDB aggregation is rewritten by Spring Data in a wrong way?

有合集

{
  "field": {
    "nested": 0
  }
}

需要获取嵌套字段的总和。由于不允许像下面这样直接操作

{
  "$group": {
    "_id": null,
    "field.nested": {
      "$sum": "$field.nested"
    }
  }
}

它是通过以下带有预投影和 post 投影的聚合完成的。

[
  {
    "$project": {
      "fieldNested": "$field.nested"
    }
  },
  {
    "$group": {
      "_id": null,
      "fieldNested": {
        "$sum": "$fieldNested"
      }
    }
  },
  {
    "$project": {
      "total": {
        "field" : {
          "nested" : "$fieldNested"
        }
      }
    }
  }
]

它在 Mongo 数据库 shell 中正常工作。问题在于以 json 格式在 Spring 数据中使用此聚合。例如,

@Repository
public interface Sample extends MongoRepository<InData, String> {

    @Aggregation({
            "" +
                    "{" +
                    "  '$project': {" +
                    "    'fieldNested': '$field.nested'" +
                    "  }" +
                    "}",
            "" +
                    "{" +
                    "  '$group': {" +
                    "    '_id': null," +
                    "    'fieldNested': {" +
                    "      '$sum': '$fieldNested'" +
                    "    }" +
                    "  }" +
                    "}",
            "" +
                    "{" +
                    "  '$project': {" +
                    "    'total': {" +
                    "      'field': {" +
                    "        'nested': '$fieldNested'" +
                    "      }" +
                    "    }" +
                    "  }" +
                    "}"
    })
    List<OutData> aggregateBy();

}

这个 json 不知何故被 Spring 数据重写,因此发送到 Mongo 的管道如下所示

[
  {
    "$project": {
      "field.nested": "$field.nested"
    }
  },
  {
    "$group": {
      "_id": null,
      "field.nested": {
        "$sum": "$fieldNested"
      }
    }
  },
  {
    "$project": {
      "total": {
        "field" : {
          "nested" : "$fieldNested"
        }
      }
    }
  }
]

fieldNested 替换为 field.nested。结果聚合失败。

为什么会这样?有什么方法可以避免 Spring Data for MongoDB 的这种重写(Spring Boot 2.2.13.RELEASE,MongoDB 3.6.8)?

Spring 数据 MongoDB 正在将 fieldNested 转换为 field.nested,因为您的 InData class 及其集合在该层次结构中有字段.如果您想使用 @Aggregation 投影该嵌套字段,则使用不属于您的 InData class 及其集合字段的任何其他名称对其进行投影,这样 Spring 数据将不会转换它.