$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
字段的文档。正如以下场景所示,您可以编写查询将 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
具有 Sales
和 Operations
角色,且能看到以下文档:
[ { _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
仍填充用户的角色。