$setIntersection (聚合)
定义
$setIntersection
接受两个或多个数组,并返回一个包含每个输入数组中出现的元素的数组。
$setIntersection
具有以下语法{ $setIntersection: [ <array1>, <array2>, ... ] }
行为
$setIntersection
对数组执行集合运算,将数组视为集合。如果数组包含重复条目,$setIntersection
会忽略重复条目。$setIntersection
忽略元素顺序。
$setIntersection
会过滤掉结果中的重复项,以输出只包含唯一条目的数组。输出数组中元素的顺序是不确定的。
如果没有找到交集(即输入数组中没有共同元素),$setIntersection
将返回一个空数组。
如果集合包含嵌套数组元素,$setIntersection
不会进入嵌套数组,而是在顶级评估数组。
示例 | 结果 | ||
---|---|---|---|
|
| ||
|
|
示例
本节包含示例,展示了如何使用 $setIntersection
与集合一起使用。
元素数组示例
假设有一个包含以下文档的 flowers
集合
db.flowers.insertMany( [ { "_id" : 1, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid" ] }, { "_id" : 2, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "orchid", "rose", "orchid" ] }, { "_id" : 3, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid", "jasmine" ] }, { "_id" : 4, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "jasmine", "rose" ] }, { "_id" : 5, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ ] }, { "_id" : 6, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose" ], [ "orchid" ] ] }, { "_id" : 7, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose", "orchid" ] ] }, { "_id" : 8, "flowerFieldA" : [ ], "flowerFieldB" : [ ] }, { "_id" : 9, "flowerFieldA" : [ ], "flowerFieldB" : [ "rose" ] } ] )
以下操作使用 $setIntersection
操作符返回 flowerFieldA
数组和 flowerFieldB
数组共有的元素数组
db.flowers.aggregate( [ { $project: { flowerFieldA: 1, flowerFieldB: 1, commonToBoth: { $setIntersection: [ "$flowerFieldA", "$flowerFieldB" ] }, _id: 0 } } ] )
操作返回以下结果
{ "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid" ], "commonToBoth" : [ "orchid", "rose" ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "orchid", "rose", "orchid" ], "commonToBoth" : [ "orchid", "rose" ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid", "jasmine" ], "commonToBoth" : [ "orchid", "rose" ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "jasmine", "rose" ], "commonToBoth" : [ "rose" ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ ], "commonToBoth" : [ ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose" ], [ "orchid" ] ], "commonToBoth" : [ ] } { "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose", "orchid" ] ], "commonToBoth" : [ ] } { "flowerFieldA" : [ ], "flowerFieldB" : [ ], "commonToBoth" : [ ] } { "flowerFieldA" : [ ], "flowerFieldB" : [ "rose" ], "commonToBoth" : [ ] }
检索当前用户授予的角色的文档
从 MongoDB 7.0 版本开始,您可以使用新的 USER_ROLES
系统变量来返回用户 角色。
本节中的场景展示了具有各种角色的用户,他们对包含预算信息的集合中的文档具有有限的访问权限。
此场景展示了 USER_ROLES
的一种可能的用途。在 budget
集合中,文档包含一个名为 allowedRoles
的字段。正如您将在以下场景中看到的那样,您可以编写查询,将这些字段中找到的用户角色与由 USER_ROLES
系统变量返回的角色进行比较。
注意
有关另一个 USER_ROLES
示例场景,请参阅 检索授予当前用户的医疗信息。该示例不将用户角色存储在文档字段中,而下面的示例则这样做。
对于本节中的预算场景,执行以下步骤以创建角色、用户和 budget
集合
创建用户
创建名为 John
和 Jane
的用户,并分配所需的角色。将 test
数据库替换为您的数据库名称。
db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } ) db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } )
创建集合
运行
db.budget.insertMany( [ { _id: 0, allowedRoles: [ "Marketing" ], comment: "For marketing team", yearlyBudget: 15000 }, { _id: 1, allowedRoles: [ "Sales" ], comment: "For sales team", yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ "Operations" ], comment: "For operations team", yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ "Development" ], comment: "For development team", yearlyBudget: 27000 } ] )
按照以下步骤检索 John
可访问的文档
检索文档
要使用系统变量,请将 $$
添加到变量名开头。指定 USER_ROLES
系统变量为 $$USER_ROLES
。
运行
db.budget.aggregate( [ { $match: { $expr: { $not: { $eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ] } } } } ] )
上一个示例返回了来自 budget
集合的文档,这些文档至少匹配运行该示例的用户具有的一个角色。为了做到这一点,示例使用 $setIntersection
来返回文档,其中 budget
文档的 allowedRoles
字段与 $$USER_ROLES
中的用户角色集合的交集不为空。
检查文档
John
拥有 Marketing
、Operations
和 Development
角色,并可以看到这些文档
[ { _id: 0, allowedRoles: [ 'Marketing' ], comment: 'For marketing team', yearlyBudget: 15000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ 'Development' ], comment: 'For development team', yearlyBudget: 27000 } ]
执行以下步骤以检索 Jane
可访问的文档
检查文档
Jane
拥有 销售
和 运营
角色,并查看这些文档
[ { _id: 1, allowedRoles: [ 'Sales' ], comment: 'For sales team', yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 } ]
注意
在分片集群上,可以由其他服务器节点代表用户在分片上执行查询。在这些查询中,USER_ROLES
仍然填充了用户的角色。