$setIntersection (aggregation)
On this page本页内容
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
不会下降到嵌套数组中,而是在顶层计算数组。
{ $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 从MongoDB 7.0开始,您可以使用新的USER_ROLES
system variable to return user roles.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
系统变量返回的角色进行比较。
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
集合:
Create the users创建用户
Create users named 创建具有所需角色的名为John
and Jane
with the required roles. Replace the test
database with your database name.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" }
]
} )
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
可访问的文档:
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
中的用户角色集之间的交集不为空的文档。
Examine the documents检查文件
John
has the Marketing
, Operations
, and Development
roles, and sees these documents: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
}
]
Perform the following steps to retrieve the documents accessible to 执行以下步骤以检索Jane
:Jane
可访问的文档:
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" ] }, [] ]
}
}
}
} ] )
Examine the documents检查文件
Jane
has the Sales
and Operations
roles, and sees these documents: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
}
]
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
仍然填充有用户的角色。