2016-03-09 98 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