定义
示例
本节的示例使用 db.collection.aggregate() 辅助函数。
评估每个文档级别的访问
forecasts 集合包含以下形式的文档,其中 tags 字段列出了该文档/嵌入式文档级别的不同访问值;即 [ "G", "STLW" ] 值指定 "G" 或 "STLW" 可以访问数据:
db.forecasts.insertOne(    {       _id: 1,       title: "123 Department Report",       tags: [ "G", "STLW" ],       year: 2014,       subsections: [          {          subtitle: "Section 1: Overview",          tags: [ "SI", "G" ],          content:  "Section 1: This is the content of section 1."          },          {          subtitle: "Section 2: Analysis",          tags: [ "STLW" ],          content: "Section 2: This is the content of section 2."          },          {          subtitle: "Section 3: Budgeting",          tags: [ "TK" ],          content: {             text: "Section 3: This is the content of section 3.",             tags: [ "HCS" ]          }          }       ]    } ) 
用户有权查看带有标签 "STLW" 或 "G" 的信息。要对该用户的所有年份为 2014 的文档运行查询,请添加 $redact 阶段,如下所示:
var userAccess = [ "STLW", "G" ]; db.forecasts.aggregate(    [    { $match: { year: 2014 } },    { $redact: {       $cond: {          if: { $gt: [ { $size: { $setIntersection: [ "$tags", userAccess ] } }, 0 ] },          then: "$$DESCEND",          else: "$$PRUNE"          }       }    }    ] ); 
该聚合操作返回以下 "redacted" 文档:
{    _id: 1,    title: "123 Department Report",    tags: [ "G", "STLW" ],    year: 2014,    subsections: [       {       subtitle: "Section 1: Overview",       tags: [ "SI", "G" ],       content: "Section 1: This is the content of section 1."       },       {       subtitle: "Section 2: Analysis",       tags: [ "STLW" ],       content : "Section 2: This is the content of section 2."       }    ] } 
排除给定级别的所有字段
集合accounts包含以下文档:
db.accounts.insertOne(    {       _id: 1,       level: 1,       acct_id: "xyz123",       cc: {          level: 5,          type: "yy",          num: 000000000000,          exp_date: ISODate("2015-11-01T00:00:00.000Z"),          billing_addr: {          level: 5,          addr1: "123 ABC Street",          city: "Some City"          },          shipping_addr: [          {             level: 3,             addr1: "987 XYZ Ave",             city: "Some City"          },          {             level: 3,             addr1: "PO Box 0123",             city: "Some City"          }          ]       },       status: "A"    } ) 
在该示例文档中,level 字段确定查看数据所需的访问权限级别。
要对状态为 A 的所有文档运行查询并排除级别为 5 的文档/嵌入式文档中包含的所有字段,请包含在 then 字段中指定系统变量 "$$PRUNE" 的 $redact 阶段:
db.accounts.aggregate(    [       { $match: { status: "A" } },       {          $redact: {          $cond: {             if: { $eq: [ "$level", 5 ] },             then: "$$PRUNE",             else: "$$DESCEND"          }          }       }    ] ); 
$redact 阶段会对 level 字段进行求值,以确定访问权限。如果 level 字段等于 5,则排除该级别的所有字段,即使已排除的字段包含可能具有不同 level 值的嵌入式文档(例如 shipping_addr 字段)。
该聚合操作返回以下 "redacted" 文档:
{    _id: 1,    level: 1,    acct_id: "xyz123",    status: "A" } 
结果集显示,$redact 阶段排除了整个 cc 字段,包括 shipping_addr 字段,该字段包含 level 字段值等于 3 而不是 5 的嵌入式文档。
提示
实施字段级日志校订以了解为同一数据设置多种访问权限组合的步骤。
本页上的 Node.js 示例使用Atlas示例数据集中的 sample_mflix数据库。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅MongoDB Node.js驾驶员文档中的入门。
要使用MongoDB Node.js驾驶员将 $redact 阶段添加到聚合管道,请在管道对象中使用 $redact操作符。
以下示例创建了一个管道阶段,用于保留 imdb.rating字段的值大于或等于 9 的文档。该阶段会排除所有其他文档。然后,该示例运行聚合管道:
const pipeline = [   {      $redact: {       $cond: {           if: { $gte: ["$imdb.rating", 9] },          then: "$$KEEP",          else: "$$PRUNE"         }     }   } ]; const cursor = collection.aggregate(pipeline); return cursor; 
了解详情
要学习;了解有关本指南中系统变量的更多信息,请参阅聚合变量页面。