MongoDB聚合运算符:$setIntersection
文章目录
- MongoDB聚合运算符:$setIntersection
- 语法
- 使用
- 举例
- 元素数组举例
- 检索授予当前用户角色的文档
- 创建角色
- 创建用户
- 创建集合
- 使用John登录
- 检索文档
- 检查文档
- 使用Jane登录
- 检索文档
- 验证文档
$setIntersection
聚合运算符返回两个或多个数组的交集。
语法
{ $setIntersection: [ <array1>, <array2>, ... ] }
字段说明:
参数可以是任何有效的数组表达式。
使用
$setIntersection
对数组执行集合操作,将数组视为集合,如果数组包含重复元素,$setIntersection
会忽略重复元素,$setIntersection
忽略元素的顺序。$setIntersection
过滤掉结果中的重复项,输出仅包含唯一元素的数组,输出数组中元素的顺序未指定。- 如果未找到交集(即输入数组不包含公共元素),则
$setIntersection
返回一个空数组。 - 如果集合包含嵌套数组元素,则
$setIntersection
不会下降到嵌套数组,而处理顶层数组。
例如 | 结果 |
---|---|
{ $setIntersection: [ [ "a", "b", "a" ], [ "b", "a" ] ] } | [ "b", "a" ] |
{ $setIntersection: [ [ "a", "b" ], [ [ "a", "b" ] ] ] } | [] |
举例
元素数组举例
使用下面的脚本创建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
系统变量来返回用户角色。
下面的例子展示了不同角色的用户对budget集合中的文档具有不同的访问权限。展示了 USER_ROLES
在进行权限检索时的一种用途,budget集合包含的文档中有一个名为 allowedRoles
的字段,在下面的场景中将会看到,可以编写查询,将 allowedRoles
字段中的用户角色与 USER_ROLES
系统变量返回的角色进行比较。
执行以下步骤创建角色、用户和budget集合:
创建角色
db.createRole( { role: "Marketing", roles: [], privileges: [] } )
db.createRole( { role: "Sales", roles: [], privileges: [] } )
db.createRole( { role: "Development", roles: [], privileges: [] } )
db.createRole( { role: "Operations", roles: [], privileges: [] } )
创建用户
创建名为 John
和 Jane
的用户,并设置所需的角色。
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
可以访问的文档:
使用John登录
db.auth( "John", "jn008" )
检索文档
使用系统变量,将 $$
添加到变量名称的开头。将 USER_ROLES
系统变量指定为 $$USER_ROLES
。
db.budget.aggregate( [ {$match: {$expr: {$not: {$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]}}}
} ] )
上例从budget
集合中返回与运行该示例的用户角色匹配的文档,使用 $setIntersection
返回budget
文档 allowedRoles
字段与 $$USER_ROLES
中的用户角色集之间的交集不为空的文档。
检查文档
John
担任营销、运营和开发角色:
[{_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登录
db.auth( "Jane", "je009" )
检索文档
要使用系统变量,可将 $$
添加到变量名称的开头。将 USER_ROLES
系统变量指定为 $$USER_ROLES
。
db.budget.aggregate( [ {$match: {$expr: {$not: {$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]}}}
} ] )
验证文档
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}
]