将 mongo 查询转换为 spring-data-mongo 查询
translate mongo query to spring-data-mongo query
我有一个使用 mongoPlayground here.
制作的查询
db.Workflow.aggregate([
{
$match: {}
},
{
$unwind: "$tasks"
},
{
"$addFields": {
"workflow": "$$ROOT"
}
},
{
"$project": {
workflowTask: "$tasks",
workflow: "$workflow"
}
},
{
$set: {
"workflowTask.workflow": "$workflow"
}
},
{
$unset: [
"workflowTask.workflow.tasks",
"workflow",
"_id"
]
},
{
$facet: {
data: [
{
$skip: 0
},
{
$limit: 30
},
],
count: [
{
$group: {
_id: null,
total: {
$sum: 1
}
}
},
],
}
}
])
我很难将其转换为 spring-data-mongo 聚合对象!
更准确地说:
- 匹配很好
- 放松一下就好了
- 项目很好
$$ROOT 变量似乎在 spring-data 中不起作用!
另外, $set 和 $unset 似乎不受支持?
最后,对于方面,我可以生成 data[] 部分,但无法生成计数:{ total: xx}
如您所见,Spring-Data 不允许定义所有合法的 MongoDB 查询。
但是,你可以玩个把戏:
所有 Spring-Data AggregationOperation
实现(MatchOperation
, AggregationOperation
, ...)变成 org.bson.Document
.
您需要做的就是使用 MongoDB JSON 查询实现 AggregationOperation
:
- 调用生成器:
new Document("$unwind", "$tasks")
- 来自 JSON:
Document.parse("{\"$unwind\": \"$tasks\"}")
// Define aggregation pipelines
List<AggregationOperation> pipeline = new ArrayList<>();
//$addFields
pipeline.add(Aggregation.addFields().addFieldWithValue("workflow", "$$ROOT").build());
//$unset
pipeline.add(agg -> new Document("$unset",
Arrays.asList(
"workflowTask.workflow.tasks",
"workflow",
"_id")));
//$facet
pipeline.add(agg -> new Document("$facet", ...))
您使用的 Spring 数据 MongoDB 是哪个版本?对于 2.5.0 版,每个操作都按以下方式进行。
MatchOperation matchOperation = Aggregation.match(new Criteria());
UnwindOperation unwindOperation = Aggregation.unwind("tasks");
AddFieldsOperation addFieldsOperation = Aggregation.addFields().addField("workflow").withValue("$$ROOT").build();
ProjectionOperation projectionOperation = Aggregation.project("_id").and("tasks").as("workflowTask").and("workflow").as("workflow");
SetOperation setOperation = SetOperation.builder().set("workflowTask.workflow").toValueOf("workflow");
UnsetOperation unsetOperation = UnsetOperation.unset("workflowTask.workflow.tasks", "workflow", "_id");
FacetOperation facetOperation = Aggregation.facet()
.and(Aggregation.skip(0L), Aggregation.limit(30))
.as("data")
.and(Aggregation.group().count().as("total"))
.as("count");
Set 和 Unset 在 Aggregation 中不可用 class 但可以直接使用。
我有一个使用 mongoPlayground here.
制作的查询db.Workflow.aggregate([
{
$match: {}
},
{
$unwind: "$tasks"
},
{
"$addFields": {
"workflow": "$$ROOT"
}
},
{
"$project": {
workflowTask: "$tasks",
workflow: "$workflow"
}
},
{
$set: {
"workflowTask.workflow": "$workflow"
}
},
{
$unset: [
"workflowTask.workflow.tasks",
"workflow",
"_id"
]
},
{
$facet: {
data: [
{
$skip: 0
},
{
$limit: 30
},
],
count: [
{
$group: {
_id: null,
total: {
$sum: 1
}
}
},
],
}
}
])
我很难将其转换为 spring-data-mongo 聚合对象!
更准确地说:
- 匹配很好
- 放松一下就好了
- 项目很好
$$ROOT 变量似乎在 spring-data 中不起作用! 另外, $set 和 $unset 似乎不受支持? 最后,对于方面,我可以生成 data[] 部分,但无法生成计数:{ total: xx}
如您所见,Spring-Data 不允许定义所有合法的 MongoDB 查询。
但是,你可以玩个把戏:
所有 Spring-Data AggregationOperation
实现(MatchOperation
, AggregationOperation
, ...)变成 org.bson.Document
.
您需要做的就是使用 MongoDB JSON 查询实现 AggregationOperation
:
- 调用生成器:
new Document("$unwind", "$tasks")
- 来自 JSON:
Document.parse("{\"$unwind\": \"$tasks\"}")
// Define aggregation pipelines
List<AggregationOperation> pipeline = new ArrayList<>();
//$addFields
pipeline.add(Aggregation.addFields().addFieldWithValue("workflow", "$$ROOT").build());
//$unset
pipeline.add(agg -> new Document("$unset",
Arrays.asList(
"workflowTask.workflow.tasks",
"workflow",
"_id")));
//$facet
pipeline.add(agg -> new Document("$facet", ...))
您使用的 Spring 数据 MongoDB 是哪个版本?对于 2.5.0 版,每个操作都按以下方式进行。
MatchOperation matchOperation = Aggregation.match(new Criteria());
UnwindOperation unwindOperation = Aggregation.unwind("tasks");
AddFieldsOperation addFieldsOperation = Aggregation.addFields().addField("workflow").withValue("$$ROOT").build();
ProjectionOperation projectionOperation = Aggregation.project("_id").and("tasks").as("workflowTask").and("workflow").as("workflow");
SetOperation setOperation = SetOperation.builder().set("workflowTask.workflow").toValueOf("workflow");
UnsetOperation unsetOperation = UnsetOperation.unset("workflowTask.workflow.tasks", "workflow", "_id");
FacetOperation facetOperation = Aggregation.facet()
.and(Aggregation.skip(0L), Aggregation.limit(30))
.as("data")
.and(Aggregation.group().count().as("total"))
.as("count");
Set 和 Unset 在 Aggregation 中不可用 class 但可以直接使用。