2016-03-09 99 views
3

我创建了一个应用程序,用于管理项目。 一个项目,如下所示:Mongodb,通过控制减少列表

{ 
    "_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"] 
     }] 
    } 
    ] 
} 

我们可以看到这里有两个不同的角色:USEROTHER

当我与USER作用上述项目,我需要有以下方面的代表,而不OTHER文件:

{ 
    "_id": ObjectId("..."), 
    "title": "MySuperProject", 
    "files": [ 
    { 
     "title":"My skiing day !", 
     "right":{ 
     "role":"USER", 
     "access":["read"] 
     } 
    }] 
} 

是否存在的方式,以减少基于文档的内部列表查询或我应该手动对结果?

我在nodejsmongoose上工作。

感谢您的帮助

编辑:其实right关键是一个ARRAY

回答

4

这是对$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阶段,我们$$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阶段。总是建议采取不同的方法,看看哪一种最适合你。

+0

感谢您的帮助。我编辑了我的问题,你的代码实际上并不适用于我:/ – mfrachet

+0

@Skahrz是的,它不会。由于您的编辑已改变了您的问题的整个上下文。将相应地更新我的帖子。 – BatScream

+0

@Skahrz编辑了我的答案。请检查它是否满足您的要求。 – BatScream