MongoDB聚合运算符:$setIntersection
文章目录
$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
}
]