Docs HomeMongoDB Manual

$setIntersection (aggregation)

Definition定义

$setIntersection

Takes two or more arrays and returns an array that contains the elements that appear in every input array.获取两个或多个数组,并返回一个数组,该数组包含出现在每个输入数组中的元素。

$setIntersection has the following syntax:具有以下语法:

{ $setIntersection: [ <array1>, <array2>, ... ] }

The arguments can be any valid expression as long as they each resolve to an array. 参数可以是任何有效的表达式,只要它们各自解析为一个数组即可。For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式

Behavior行为

$setIntersection performs set operation on arrays, treating arrays as sets. 对数组执行set操作,将数组视为集合。If an array contains duplicate entries, $setIntersection ignores the duplicate entries. 如果数组包含重复的条目,$setIntersection将忽略重复的条目。$setIntersection ignores the order of the elements.忽略元素的顺序。

$setIntersection filters out duplicates in its result to output an array that contain only unique entries. 筛选掉结果中的重复项,以输出仅包含唯一项的数组。The order of the elements in the output array is unspecified.输出数组中元素的顺序未指定。

If no intersections are found (i.e. the input arrays contain no common elements), $setIntersection returns an empty array.如果没有找到交集(即输入数组不包含公共元素),$setIntersection将返回一个空数组。

If a set contains a nested array element, $setIntersection does not descend into the nested array but evaluates the array at top-level.如果集合包含嵌套数组元素,则$setIntersection不会下降到嵌套数组中,而是在顶层计算数组。

Example示例Result结果
{ $setIntersection: [ [ "a", "b", "a" ], [ "b", "a" ] ] }
[ "b", "a" ]
{ $setIntersection: [ [ "a", "b" ], [ [ "a", "b" ] ] ] }
[ ]

Examples实例

This section contains examples that show the use of $setIntersection with collections.本节包含的示例显示了$setIntersection与集合的使用。

Elements Array Example元素数组示例

Consider an flowers collection with the following documents:考虑一个包含以下文件的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" ] }
] )

The following operation uses the $setIntersection operator to return an array of elements common to both the flowerFieldA array and the flowerFieldB array:以下操作使用$setIntersection运算符返回flowerFieldA数组和flowerFieldB数组共有的元素数组:

db.flowers.aggregate(
[
{ $project: { flowerFieldA: 1, flowerFieldB: 1, commonToBoth: { $setIntersection: [ "$flowerFieldA", "$flowerFieldB" ] }, _id: 0 } }
]
)

The operation returns the following results:该操作返回以下结果:

{ "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" : [ ] }

Retrieve Documents for Roles Granted to the Current User检索授予当前用户的角色的文档

Starting in MongoDB 7.0, you can use the new USER_ROLES system variable to return user roles.从MongoDB 7.0开始,您可以使用新的USER_ROLES系统变量来返回用户角色

The scenario in this section shows users with various roles who have limited access to documents in a collection containing budget information.本节中的场景显示了具有各种角色的用户,他们对包含预算信息的集合中的文档的访问权限有限。

The scenario shows one possible use of USER_ROLES. 该场景显示了USER_ROLES的一种可能用途。The budget collection contains documents with a field named allowedRoles. budget集合包含一个名为allowedRoles的字段的文档。As you'll see in the following scenario, you can write queries that compare the user roles found in the allowedRoles field with the roles returned by the USER_ROLES system variable.正如您在下面的场景中看到的那样,您可以编写查询,将allowedRoles字段中的用户角色与USER_ROLES系统变量返回的角色进行比较。

Note

For another USER_ROLES example scenario, see Retrieve Medical Information for Roles Granted to the Current User. 有关另一个USER_ROLES示例场景,请参阅检索授予当前用户的角色的医疗信息That example doesn't store the user roles in the document fields, as is done in the following example.该示例不会像下面的示例那样将用户角色存储在文档字段中。

For the budget scenario in this section, perform the following steps to create the roles, users, and budget collection:对于本节中的预算方案,请执行以下步骤来创建角色、用户和budget集合:

1

Create the roles创建角色

Run:运行:

db.createRole( { role: "Marketing", roles: [], privileges: [] } )
db.createRole( { role: "Sales", roles: [], privileges: [] } )
db.createRole( { role: "Development", roles: [], privileges: [] } )
db.createRole( { role: "Operations", roles: [], privileges: [] } )
2

Create the users创建用户

Create users named John and Jane with the required roles. Replace the test database with your database name.创建具有所需角色的名为JohnJane的用户。将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" }
]
} )
3

Create the collection创建集合

Run:运行:

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
}
] )

Perform the following steps to retrieve the documents accessible to John:执行以下步骤以检索John可访问的文档:

1

Log in as John以John身份登录

Run:运行:

db.auth( "John", "jn008" )
2

Retrieve the documents检索文档

To use a system variable, add $$ to the start of the variable name. 要使用系统变量,请在变量名的开头添加$$Specify the USER_ROLES system variable as $$USER_ROLES.USER_ROLES系统变量指定为$$USER_ROLES

Run:

db.budget.aggregate( [ {
$match: {
$expr: {
$not: {
$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]
}
}
}
} ] )

The previous example returns the documents from the budget collection that match at least one of the roles that the user who runs the example has. 上一个示例返回budget集合中与运行该示例的用户所具有的至少一个角色相匹配的文档。To do that, the example uses $setIntersection to return documents where the intersection between the budget document allowedRoles field and the set of user roles from $$USER_ROLES is not empty.为此,该示例使用$setIntersection返回预算文档allowedRoles字段和$$USER_ROLES中的用户角色集之间的交集不为空的文档。

3

Examine the documents检查文件

John has the Marketing, Operations, and Development roles, and sees these documents:John负责MarketingOperationsDevelopment,并查看以下文档:

[
{
_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
}
]

Perform the following steps to retrieve the documents accessible to Jane:执行以下步骤以检索Jane可访问的文档:

1

Log in as Jane以Jane身份登录

Run:运行:

db.auth( "Jane", "je009" )
2

Retrieve the documents检索文档

To use a system variable, add $$ to the start of the variable name. 要使用系统变量,请在变量名的开头添加$$Specify the USER_ROLES system variable as $$USER_ROLES.USER_ROLES系统变量指定为$$USER_ROLES

Run:运行:

db.budget.aggregate( [ {
$match: {
$expr: {
$not: {
$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]
}
}
}
} ] )
3

Examine the documents检查文件

Jane has the Sales and Operations roles, and sees these documents:Jane担任SalesOperations角色,并查看以下文档:

[
{
_id: 1,
allowedRoles: [ 'Sales' ],
comment: 'For sales team',
yearlyBudget: 17000,
salesEventsBudget: 1000
},
{
_id: 2,
allowedRoles: [ 'Operations' ],
comment: 'For operations team',
yearlyBudget: 19000,
cloudBudget: 12000
}
]
Note

On a sharded cluster, a query can be run on a shard by another server node on behalf of the user. 在分片集群上,另一个服务器节点可以代表用户在分片上运行查询。In those queries, USER_ROLES is still populated with the roles for the user.在这些查询中,USER_ROLES仍然填充有用户的角色。