Mongodb select 特定元素构成嵌套文档
Mongodb select particular element form an nested document
我有以下 MongoDB 对象结构。我想 select aclpermissions 基于值(使用 Spring MogoTemplate)。例如如果我通过“58dc0bea0cd182789fc62fab”,它应该 return 只有 aclpermissions.READ,但如果我通过“58dc0bd70cd182789fc62faa”,它应该 return 所有 aclpermissions。
如何实现。如果我必须修改数据结构,请建议该怎么做以及如何实现。
{
"_id" : ObjectId("5900d6abb9eb284a78f5a350"),
"_class" : "com.debopam.amsapp.model.AMSAppACL",
"attrUniqueCode" : "USER",
"attributeVersion" : 1,
"aclpermissions" : {
"CRT" : [
"58dc0bd70cd182789fc62faa"
],
"READ" : [
"58dc0bd70cd182789fc62faa",
"58dc0bea0cd182789fc62fab"
],
"UPD" : [
"58dc0bd70cd182789fc62faa"
],
"DLT" : [
"58dc0bd70cd182789fc62faa"
]
},
"orgHierachyIdentifier" : "14",
"orgid" : 14,
"createDate" : ISODate("2017-04-26T17:19:39.026Z"),
"lastModifiedDate" : ISODate("2017-04-26T17:19:39.026Z"),
"createdBy" : "appadmin",
"lastModifiedBy" : "appadmin"
}
您可以使用来自
的相同更新结构
您可以将下面的聚合查询与 $filter
数组运算符和 $setIsSubset
查询运算符结合使用,它比较并选择输入值为 aclpermission.v
的子集的嵌套文档。
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static java.util.Arrays.asList;
Aggregation aggregation = newAggregation(
match(Criteria.where("_id").is(new ObjectId("5900d6abb9eb284a78f5a350"))),
project()
.and(filter("aclpermissions")
.as("aclpermission")
.by(aggregationOperationContext -> new BasicDBObject("$setIsSubset", asList(asList("58dc0bd70cd182789fc62faa"), "$$aclpermission.v"))))
.as("aclpermissions")
);
List<BasicDBObject> results = mongoTemplate.aggregate(aggregation, collectionName, BasicDBObject.class).getMappedResults();
Mongo Shell 查询:
aggregate([ { "$match" : { "_id" : ObjectId("5900d6abb9eb284a78f5a350")}} , { "$project" : { "aclpermissions" : { "$filter" : { "input" : "$aclpermissions" , "as" : "aclpermission" , "cond" : { "$setIsSubset" : [ ["58dc0bd70cd182789fc62faa"], "$$aclpermission.v"]}}}}}])
更新:
下面的查询将 $match
个 attrUniqueCode
值等于 USER
的文档,后跟 $sort
和 $group
选择最新的文档。 $$ROOT
是表达式变量,用于访问整个文档 $first
以获取最新的文档。
Aggregation aggregation = newAggregation(
match(Criteria.where("attrUniqueCode").is("USER")),
sort(new Sort(Sort.Direction.DESC, "attributeVersion")),
group().first("$$ROOT").as("latest"),
project("latest._id", "latest.attrUniqueCode", "latest.attributeVersion")
.and(filter("latest.aclpermissions")
.as("aclpermission")
.by(aggregationOperationContext -> new BasicDBObject("$setIsSubset", asList(asList("58dc0bd70cd182789fc62faa"), "$$aclpermission.v"))))
.as("aclpermissions")
);
参考
https://docs.mongodb.com/manual/reference/aggregation-variables/
https://docs.mongodb.com/manual/reference/operator/aggregation/project/
https://docs.mongodb.com/manual/reference/operator/aggregation/filter/
我有以下 MongoDB 对象结构。我想 select aclpermissions 基于值(使用 Spring MogoTemplate)。例如如果我通过“58dc0bea0cd182789fc62fab”,它应该 return 只有 aclpermissions.READ,但如果我通过“58dc0bd70cd182789fc62faa”,它应该 return 所有 aclpermissions。
如何实现。如果我必须修改数据结构,请建议该怎么做以及如何实现。
{
"_id" : ObjectId("5900d6abb9eb284a78f5a350"),
"_class" : "com.debopam.amsapp.model.AMSAppACL",
"attrUniqueCode" : "USER",
"attributeVersion" : 1,
"aclpermissions" : {
"CRT" : [
"58dc0bd70cd182789fc62faa"
],
"READ" : [
"58dc0bd70cd182789fc62faa",
"58dc0bea0cd182789fc62fab"
],
"UPD" : [
"58dc0bd70cd182789fc62faa"
],
"DLT" : [
"58dc0bd70cd182789fc62faa"
]
},
"orgHierachyIdentifier" : "14",
"orgid" : 14,
"createDate" : ISODate("2017-04-26T17:19:39.026Z"),
"lastModifiedDate" : ISODate("2017-04-26T17:19:39.026Z"),
"createdBy" : "appadmin",
"lastModifiedBy" : "appadmin"
}
您可以使用来自
您可以将下面的聚合查询与 $filter
数组运算符和 $setIsSubset
查询运算符结合使用,它比较并选择输入值为 aclpermission.v
的子集的嵌套文档。
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static java.util.Arrays.asList;
Aggregation aggregation = newAggregation(
match(Criteria.where("_id").is(new ObjectId("5900d6abb9eb284a78f5a350"))),
project()
.and(filter("aclpermissions")
.as("aclpermission")
.by(aggregationOperationContext -> new BasicDBObject("$setIsSubset", asList(asList("58dc0bd70cd182789fc62faa"), "$$aclpermission.v"))))
.as("aclpermissions")
);
List<BasicDBObject> results = mongoTemplate.aggregate(aggregation, collectionName, BasicDBObject.class).getMappedResults();
Mongo Shell 查询:
aggregate([ { "$match" : { "_id" : ObjectId("5900d6abb9eb284a78f5a350")}} , { "$project" : { "aclpermissions" : { "$filter" : { "input" : "$aclpermissions" , "as" : "aclpermission" , "cond" : { "$setIsSubset" : [ ["58dc0bd70cd182789fc62faa"], "$$aclpermission.v"]}}}}}])
更新:
下面的查询将 $match
个 attrUniqueCode
值等于 USER
的文档,后跟 $sort
和 $group
选择最新的文档。 $$ROOT
是表达式变量,用于访问整个文档 $first
以获取最新的文档。
Aggregation aggregation = newAggregation(
match(Criteria.where("attrUniqueCode").is("USER")),
sort(new Sort(Sort.Direction.DESC, "attributeVersion")),
group().first("$$ROOT").as("latest"),
project("latest._id", "latest.attrUniqueCode", "latest.attributeVersion")
.and(filter("latest.aclpermissions")
.as("aclpermission")
.by(aggregationOperationContext -> new BasicDBObject("$setIsSubset", asList(asList("58dc0bd70cd182789fc62faa"), "$$aclpermission.v"))))
.as("aclpermissions")
);
参考
https://docs.mongodb.com/manual/reference/aggregation-variables/ https://docs.mongodb.com/manual/reference/operator/aggregation/project/ https://docs.mongodb.com/manual/reference/operator/aggregation/filter/