Docs Menu

$setIntersection (aggregation)

項目一覧

$setIntersection

Takes two or more arrays and returns an array that contains the elements that appear in every input array.

$setIntersectionの構文は次のとおりです。

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

引数は、それぞれが配列に変換される限り、どのような有効なでも使用できます。 式の詳細については、「式演算子 」を参照してください。

$setIntersectionは、配列をセットとして扱い、配列に対してセット演算を実行します。 配列に重複エントリが含まれている場合、 $setIntersectionは重複エントリを無視します。 $setIntersectionは要素の順序を無視します。

$setIntersectionは結果内の重複を除外して、一意のエントリのみを含む配列を出力します。 出力配列内の要素の順序は指定されていません。

If no intersections are found (i.e. the input arrays contain no common elements), $setIntersection returns an empty array.

セットにネストされた配列要素が含まれている場合、 $setIntersectionはネストされた配列に下降 せ、最上位の配列を評価します。

結果
{ $setIntersection: [ [ "a", "b", "a" ], [ "b", "a" ] ] }
[ "b", "a" ]
{ $setIntersection: [ [ "a", "b" ], [ [ "a", "b" ] ] ] }
[ ]

This section contains examples that show the use of $setIntersection with collections.

以下のドキュメントを持つ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:

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 の使用法の 1 つを示しています。budget コレクションには、 allowedRoles という名前のフィールドを持つドキュメントが含まれています。次のシナリオで示すように、allowedRoles フィールドにあるユーザー ロールと USER_ROLES システム変数によって返されるロールを比較するクエリを作成できます。

注意

別の USER_ROLES シナリオの例については、「現在のユーザーに付与されているロールの医療情報の取得」を参照してください。その例では、次の例とは異なり、ドキュメントフィールドにユーザーロールを保存しません。

このセクションの予算シナリオでは、次の手順を実行してロール、ユーザー、および budget コレクションを作成します。

1

実行:

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

必要なロールを持つ 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" }
]
} )
3

実行:

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 がアクセス可能なドキュメントを取得するには、次の手順を実行します。

1

実行:

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

システム変数を使用するには、変数名の先頭に $ を追加します。システム変数 USER_ROLES$USER_ROLES として指定します。

実行:

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. 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.

3

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

Jane がアクセス可能なドキュメントを取得するには、次の手順を実行します。

1

実行:

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

システム変数を使用するには、変数名の先頭に $ を追加します。システム変数 USER_ROLES$USER_ROLES として指定します。

実行:

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

JaneSalesOperations のロールを持ち、次のドキュメントを参照します。

[
{
_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 には引き続きユーザーのロールが使用されます。

項目一覧