将 mongo 查询转换为 spring-data-mongo 查询
Posted
技术标签:
【中文标题】将 mongo 查询转换为 spring-data-mongo 查询【英文标题】:translate mongo query to spring-data-mongo query 【发布时间】:2022-01-17 04:32:05 【问题描述】:我有一个使用 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
【问题讨论】:
【参考方案1】:您使用的是哪个版本的 Spring Data 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 类中不可用,但可以直接使用。
【讨论】:
【参考方案2】:正如您所观察到的,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", ...))
AggregationOperation
【讨论】:
以上是关于将 mongo 查询转换为 spring-data-mongo 查询的主要内容,如果未能解决你的问题,请参考以下文章
将Mongo查询转换为spring Mongooperations
将 $facet mongo 查询转换为 Spring Data