创建聚合管道时 AccumulatorOperators Max 出现问题
Issue with AccumulatorOperators Max when creating aggregation pipeline
我正在尝试将以下 Mongo shell 聚合查询转换为 Spring 数据 MongoDB 聚合:
db.getCollection('Orders').aggregate([
{ $group: {
"_id": {"book":"$bookingId"},
"docs": {$push: '$$ROOT'}
}
},
{$project: {
latestOrd: {
$filter: {
input: "$docs",
as: "item",
cond: { $eq: ["$$item.bookingVersion", { $max: "$docs.bookingVersion" }] }
}
}
}
},
{ $unwind: "$latestOrd" },
{ $replaceRoot:{newRoot:"$latestOrd"}}
])
查询获取所有预订版本最高的订单(例如,一个预订 ID 可能有许多版本为 3 的文档)。
此查询在 Mongo shell 中运行良好,但我对 Spring 的数据版本有疑问:
Aggregation.group("bookingId").push(Aggregation.ROOT).as("docs");
Aggregation.project().and(filter("docs")
.as("item")
.by(valueOf("item.bookingVersion")
.equalToValue(AccumulatorOperators.Max.maxOf("docs.bookingVersion"))))
.as("latestOrd");
Aggregation.unwind("latestOrd");
Aggregation.replaceRoot("latestOrd");
Spring 生成 Mongo 查询类似于我在上面提供的查询,除了 $max accumulator:
{ "$max" : "$$docs.bookingVersion" }
出于某种原因,它添加了双美元符号而不是单美元符号,结果我出现了以下错误:
'Use of undefined variable: docs' on server 127.0.0.1:27017
我正在使用 spring-boot-starter 2.1.0.RELEASE 和 Mongo 服务器的 4.2 版本。
感谢您对此提供的任何帮助。
输入文件:
[
{
"_id": "5f847811ebcd1a51a0196736",
"status": "REJECTED",
"bookingId": "1",
"bookingVersion": 4,
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196735",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 4,
"docNumber": "7",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196734",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 3,
"docNumber": "6",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196738",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 1,
"docNumber": "8",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196737",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 2,
"docNumber": "9",
"operation": "CREATE"
}
]
预期输出:
[
{
"_id": "5f847811ebcd1a51a0196736",
"status": "REJECTED",
"bookingId": "1",
"bookingVersion": 4,
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196735",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 4,
"docNumber": "7",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196737",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 2,
"docNumber": "9",
"operation": "CREATE"
}
]
问题可能与 2.1.0.RELEASE 版本的 spring 引导有关,但升级它对我来说不是一个选项。
为了完成这项工作,我创建了 AggregationExpression 而不是 AccumulatorOperators.Max.maxOf("docs.bookingVersion")
部分。
这里有一个方法:
private AggregationExpression buildMaxExpression() {
return new AggregationExpression() {
@Override
public Document toDocument(final AggregationOperationContext context) {
return new Document("$max", "$docs.bookingVersion");
}
};
}
我正在尝试将以下 Mongo shell 聚合查询转换为 Spring 数据 MongoDB 聚合:
db.getCollection('Orders').aggregate([
{ $group: {
"_id": {"book":"$bookingId"},
"docs": {$push: '$$ROOT'}
}
},
{$project: {
latestOrd: {
$filter: {
input: "$docs",
as: "item",
cond: { $eq: ["$$item.bookingVersion", { $max: "$docs.bookingVersion" }] }
}
}
}
},
{ $unwind: "$latestOrd" },
{ $replaceRoot:{newRoot:"$latestOrd"}}
])
查询获取所有预订版本最高的订单(例如,一个预订 ID 可能有许多版本为 3 的文档)。
此查询在 Mongo shell 中运行良好,但我对 Spring 的数据版本有疑问:
Aggregation.group("bookingId").push(Aggregation.ROOT).as("docs");
Aggregation.project().and(filter("docs")
.as("item")
.by(valueOf("item.bookingVersion")
.equalToValue(AccumulatorOperators.Max.maxOf("docs.bookingVersion"))))
.as("latestOrd");
Aggregation.unwind("latestOrd");
Aggregation.replaceRoot("latestOrd");
Spring 生成 Mongo 查询类似于我在上面提供的查询,除了 $max accumulator:
{ "$max" : "$$docs.bookingVersion" }
出于某种原因,它添加了双美元符号而不是单美元符号,结果我出现了以下错误:
'Use of undefined variable: docs' on server 127.0.0.1:27017
我正在使用 spring-boot-starter 2.1.0.RELEASE 和 Mongo 服务器的 4.2 版本。 感谢您对此提供的任何帮助。
输入文件:
[
{
"_id": "5f847811ebcd1a51a0196736",
"status": "REJECTED",
"bookingId": "1",
"bookingVersion": 4,
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196735",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 4,
"docNumber": "7",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196734",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 3,
"docNumber": "6",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196738",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 1,
"docNumber": "8",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196737",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 2,
"docNumber": "9",
"operation": "CREATE"
}
]
预期输出:
[
{
"_id": "5f847811ebcd1a51a0196736",
"status": "REJECTED",
"bookingId": "1",
"bookingVersion": 4,
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196735",
"status": "CREATED",
"bookingId": "1",
"bookingVersion": 4,
"docNumber": "7",
"operation": "CREATE"
},
{
"_id": "5f847811ebcd1a51a0196737",
"status": "CREATED",
"bookingId": "2",
"bookingVersion": 2,
"docNumber": "9",
"operation": "CREATE"
}
]
问题可能与 2.1.0.RELEASE 版本的 spring 引导有关,但升级它对我来说不是一个选项。
为了完成这项工作,我创建了 AggregationExpression 而不是 AccumulatorOperators.Max.maxOf("docs.bookingVersion")
部分。
这里有一个方法:
private AggregationExpression buildMaxExpression() {
return new AggregationExpression() {
@Override
public Document toDocument(final AggregationOperationContext context) {
return new Document("$max", "$docs.bookingVersion");
}
};
}