spring data中如何编写Replace root和merge对象聚合操作

Posted

技术标签:

【中文标题】spring data中如何编写Replace root和merge对象聚合操作【英文标题】:How to write Replace root and merge objects aggregation operation in spring data 【发布时间】:2019-09-06 02:08:28 【问题描述】:

我编写了一个 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 中,我在下面尝试但卡在替换根目录:

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());

我无法在替换根中找到合适的方法来接受数组并执行合并。请帮忙。

【问题讨论】:

【参考方案1】:

如果您不想更改“内容”字段名称,您可以使用:

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));

【讨论】:

佩德罗,感谢您抽出宝贵时间。我尝试了您的解决方案,但它给了我一个错误:Command failed with error 40400 (Location40400): '$mergeObjects requires object inputs, but input [....] 请您指导我。问题是 $contents 是一个数组。所以我找不到支持这个的方法。

以上是关于spring data中如何编写Replace root和merge对象聚合操作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用spring-data-solr编写查询,返回特定字段的所有值的列表

r语言createdatapartition在哪个函数中

如何在 spring-data 中使用子图(使用休眠)?

R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象

R:在用户定义的函数中使用 get 和 data.table

如何使用 Spring Data 获取数据