为什么 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 数据将不会转换它.
有合集
{
"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 数据将不会转换它.