我正在构建一个用于管理项目的应用程序.
一个项目如下所示:
{
"_id": ObjectId("..."),
"title": "MySuperProject",
"files": [
{
"title":"My skiing day !",
"right":[{
"role":"USER",
"access":["read"]
}]
},
{
"title":"My little dog, so cute !",
"right":[{
"role":"OTHER",
"access":["read"]
}]
}
]
}
我们在这里可以看到两个不同的角色:USER和OTHER.
当我获得具有USER角色的上述项目时,我需要具有以下表示形式,而没有OTHER文件:
{
"_id": ObjectId("..."),
"title": "MySuperProject",
"files": [
{
"title":"My skiing day !",
"right":{
"role":"USER",
"access":["read"]
}
}]
}
它是否存在一种基于查询来减少文档内部列表的方法,还是应该根据结果手动创建它?
我正在研究nodejs和mongoose.
谢谢你的帮助
编辑:实际上,右键是数组
解决方法:
这是$redact
阶段的经典用例之一.您可以将其汇总如下:
var role = "USER";
var projectTitle = "MySuperProject";
db.t.aggregate([
{
$match: {
"title":projectTitle
}
},
{
$redact: {
$cond: [{
$eq: [role, {
$ifNull: ["$role", role]
}]
}, "$$DESCEND", "$$PRUNE"]
}
}
])
输出:
{
"_id" : 1,
"title" : "MySuperProject",
"files" : [
{
"title" : "My skiing day !",
"right" : [
{
"role" : "USER",
"access" : [
"read"
]
}
]
},
{
"title" : "My little dog, so cute !",
"right" : [ ]
}
]
}
在每个级别上,仅当特定级别的文档对$redact阶段提供的$cond
返回true时,才对文档进行评估,我们将$$DESCEND
返回其子文档,否则返回$$PRUNE
.
它会列出您每个项目的所有文件,以及每个文件的访问角色数组.如果要排除“用户”没有权限的文件,则可以再次$redact:
db.t.aggregate([
{
$match: {
"title": projectTitle
}
},
{
$redact: {
$cond: [{
$eq: [role, {
$ifNull: ["$role", role]
}]
}, "$$DESCEND", "$$PRUNE"]
}
},
{
$redact: {
$cond: [{
$gt: [{
$size: {
$ifNull: ["$right", [1]]
}
}, 0]
}, "$$DESCEND", "$$PRUNE"]
}
},
])
输出:
{
"_id" : 1,
"title" : "MySuperProject",
"files" : [
{
"title" : "My skiing day !",
"right" : [
{
"role" : "USER",
"access" : [
"read"
]
}
]
}
]
}
以上方法避免了昂贵的$unwind阶段.始终建议采取不同的方法,然后看看哪种方法最适合您.