MongoDB Spring 数据给出在 class 异常中找不到 属性 '$$value'
MongoDB Spring Data gives No property '$$value' found on class exception
//Sample Collection
{
//fields
"roleList" : [ROLE_1, ROLE_2, ROLE_3],
"siteList" : [
{
"role" : ROLE_1,
//fields
},
{
"role" : ROLE_2,
//fields
},
]
}
//Expected Output
{
//fields
"roleDiff":[ROLE_3] // roleList subtracted by set of roles present in siteList
}
//Script that works with Studio 3t
db.getCollection("SAMPLE_COLLECTION").aggregate(
// Pipeline
[
// Stage 1
{
$project: {
"roleList":1,
"siteRoles":{$ifNull: [{$reduce:{
input:"$siteList",
initialValue:[],
in:{$setUnion:["$$value", {
"$split": ["$$this.role", " "]}]}
}
}, []]}
}
},
// Stage 2
{
$project: {
"roleDiff":{ $setDifference:["$roleList", "$siteRoles"]
}
}
},
],
// Options
{
}
// Created with Studio 3T, the IDE for MongoDB - https://studio3t.com/
);
ArrayOperators.Reduce reduce = ArrayOperators.Reduce.arrayOf("siteList").withInitialValue(Collections.EMPTY_SET)
.reduce(SetOperators.SetUnion.arrayAsSet(StringOperators.valueOf("$$this.role").split(" ")).union(ArrayOperators.Reduce.Variable.VALUE.getTarget()));
ProjectionOperation projectionOperationOne = Aggregation.project().andInclude(/*Some fields,*/ "roleList").and(ConditionalOperators.ifNull(reduce).then(Collections.EMPTY_LIST)).as("siteRoles");
ProjectionOperation projectionOperationTwo = Aggregation.project().andInclude(/*Some fields*/).and(SetOperators.SetDifference.arrayAsSet("roleList").differenceTo("siteRoles")).as("roleDiff");
Aggregation aggregation = Aggregation.newAggregation(projectionOperationOne, projectionOperationTwo);
AggregationResults<SiteDiff> siteDiff = mongoTemplate.aggregate(aggregation, SampleCollection.class, SiteDiff.class);
上面的Java代码抛出异常
org.springframework.data.mapping.context.InvalidPersistentPropertyPath:在 class 上未找到 属性“$$value” 您的意思是:?
该查询适用于 Studio3T。我的目的是找出 2 个字符串数组“roleList”和“siteRoles”以及记录中的其他一些字段之间的区别。
“siteRoles”必须派生自“siteList”,它是一个对象数组。由于 $addToSet 仅适用于 $group 操作,我发现很难从“siteList”中提取角色。我在这里使用 reduce 将它与 setUnion 结合起来。问题是角色是一个字符串,我不得不将它转换为数组。我能找到的唯一方法是使用 $split 并使用“”作为分隔符,因为我确定角色不会有 space。
最后,该脚本在 studio3t 中运行,但 java 版本未执行。
如果您引用嵌入式数组中的字段,它应该为您提供这些值的整个数组。
聚合应该只需要 1 个阶段:
{$project: {roleDiff: { $setDifference: ["$roleList","$siteList.role"]}}}
//Sample Collection { //fields "roleList" : [ROLE_1, ROLE_2, ROLE_3], "siteList" : [ { "role" : ROLE_1, //fields }, { "role" : ROLE_2, //fields }, ] } //Expected Output { //fields "roleDiff":[ROLE_3] // roleList subtracted by set of roles present in siteList }
//Script that works with Studio 3t db.getCollection("SAMPLE_COLLECTION").aggregate( // Pipeline [ // Stage 1 { $project: { "roleList":1, "siteRoles":{$ifNull: [{$reduce:{ input:"$siteList", initialValue:[], in:{$setUnion:["$$value", { "$split": ["$$this.role", " "]}]} } }, []]} } }, // Stage 2 { $project: { "roleDiff":{ $setDifference:["$roleList", "$siteRoles"] } } }, ], // Options { } // Created with Studio 3T, the IDE for MongoDB - https://studio3t.com/ );
ArrayOperators.Reduce reduce = ArrayOperators.Reduce.arrayOf("siteList").withInitialValue(Collections.EMPTY_SET)
.reduce(SetOperators.SetUnion.arrayAsSet(StringOperators.valueOf("$$this.role").split(" ")).union(ArrayOperators.Reduce.Variable.VALUE.getTarget()));
ProjectionOperation projectionOperationOne = Aggregation.project().andInclude(/*Some fields,*/ "roleList").and(ConditionalOperators.ifNull(reduce).then(Collections.EMPTY_LIST)).as("siteRoles");
ProjectionOperation projectionOperationTwo = Aggregation.project().andInclude(/*Some fields*/).and(SetOperators.SetDifference.arrayAsSet("roleList").differenceTo("siteRoles")).as("roleDiff");
Aggregation aggregation = Aggregation.newAggregation(projectionOperationOne, projectionOperationTwo);
AggregationResults<SiteDiff> siteDiff = mongoTemplate.aggregate(aggregation, SampleCollection.class, SiteDiff.class);
上面的Java代码抛出异常 org.springframework.data.mapping.context.InvalidPersistentPropertyPath:在 class 上未找到 属性“$$value” 您的意思是:? 该查询适用于 Studio3T。我的目的是找出 2 个字符串数组“roleList”和“siteRoles”以及记录中的其他一些字段之间的区别。 “siteRoles”必须派生自“siteList”,它是一个对象数组。由于 $addToSet 仅适用于 $group 操作,我发现很难从“siteList”中提取角色。我在这里使用 reduce 将它与 setUnion 结合起来。问题是角色是一个字符串,我不得不将它转换为数组。我能找到的唯一方法是使用 $split 并使用“”作为分隔符,因为我确定角色不会有 space。 最后,该脚本在 studio3t 中运行,但 java 版本未执行。
如果您引用嵌入式数组中的字段,它应该为您提供这些值的整个数组。
聚合应该只需要 1 个阶段:
{$project: {roleDiff: { $setDifference: ["$roleList","$siteList.role"]}}}