mongodb - spring data中如何编写Replace root和merge对象聚合操作
问题描述
我编写了一个按预期工作的 MongoDB 本机查询。我正在尝试编写其 Spring 数据等效查询,但无法这样做。基本上,我想根据输入数组中提供的标题过滤掉字段数组。这是示例文档:
{
"domain":"diageotest.com",
"locale":"en-gb",
"pageName":"Content_1",
"contents":[
{
"contentName":"Template_1",
"fields":[
{
"id":"firstname",
"fieldType":"Plain Text",
"title":"First Name",
"value":"Pawan"
},
{
"id":"lastname",
"fieldType":"Plain Text",
"title":"Last Name",
"value":"Kumar"
}
]
}
],
"createdBy":"ag-KumarJog",
"createdDate":"Jan 23,2019",
"isDefaultLocale":true,
"modifiedBy":"ag-KumarJog",
"modifiedDate":"Jan 23,2019",
"version":1
}
以下是我的本机查询:
db.contents.aggregate([
{$match: { $and: [
{"domain": "diageotest.com"},
{"locale": {$in: ["en-in", "en-us"]}},
{"contents.contentName": "Template_1"}
]
}
},
{$unwind: "$contents"},
{$unwind: "$contents.fields"},
{$match: { "contents.fields.title": {$in: ["First Name"]}}},
{$group: { "_id": "$_id",
"contents": { "$push": "$contents"},
"root": {$first:"$$ROOT"} }},
{$replaceRoot:{newRoot:{$mergeObjects:["$root",{contents:'$contents'}]}}},
{$skip : 0},
{$limit : 5}
]);
在这里,在上面的查询中,如果我在数组中传递“名字”($in 条件),那么输出 JSON 将只包含标题为“名字”的字段。
在java中,我在下面尝试但卡在replace root:
MatchOperation matchOperation = this.matchByTemplateDomainAndLocales(domainName, templateName,
requestBody.getLocales());
// ---------------------------------------------------//
UnwindOperation unwindContents = unwind("$contents");
UnwindOperation unwindFields = unwind("$contents.fields");
MatchOperation matchFields = match(where("contents.fields.title").in(requestBody.getFields()));
GroupOperation groupOperation = group("id").push("$contents").as("contents").first("$$ROOT").as("root");
//ReplaceRootOperation replaceRootOperation = builder().withDocument()
// ---------------------------------------------------//
SortOperation sortOperation = sort(sort);
LimitOperation limitOperation = limit(requestBody.getLimit());
SkipOperation skipOperation = skip(requestBody.getSkip().longValue());
我无法找到合适的方法来替换接受数组并执行合并的根。请帮忙。
解决方案
如果您不想更改“内容”字段名称,您可以使用:
ReplaceRootOperation operation = replaceRoot().withValueOf(ObjectOperators.valueOf("$root").mergeWith("$content"));
否则,不确定这是否是最干净的解决方案,但您可以这样创建它:
Map<String, String> fieldMapping = new HashMap<>();
fieldMapping.put("content", "$content");
ReplaceRootOperation operation = replaceRoot().withValueOf(ObjectOperators.valueOf("$root").mergeWith(fieldMapping));
推荐阅读
- elasticsearch - 聚合是否可以将所有分组文档中的数组属性的所有值合并到合并文档中?
- javascript - JavaScript scroll() event endless loop when page scrolled to the bottom
- python - 将 Spark DataFrame 的架构转换为另一个 DataFrame
- python - 从噪声图像中提取数字
- angular - 在 ionic 5 或 Angular 应用程序中显示 HTML 内容中的图像
- centos - 指定 Arch 时 Repodiff 不能按预期工作的任何原因?
- python - 为什么我在使用 pip 的 docker 中遇到 SSL 问题
- python - 使用 concurrent.futures.ProcessPoolExecutor 作为 loop.run_in_executor() 的执行程序的异步可迭代处理
- autohotkey - 如何在 AHK 中对 mouseclick 事件创建等效的“$”效果?
- jquery - 单击复选框时显示/隐藏 li 的子项