$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
はネストされた配列に下降 せず、最上位の配列を評価します。
例 | 結果 | ||
---|---|---|---|
|
| ||
|
|
例
This section contains examples that show the use of $setIntersection
with collections.
Elements Array Example
以下のドキュメントを持つ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
コレクションを作成します。
ユーザーの作成
必要なロールを持つ 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" } ] } )
コレクションの作成
実行:
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
がアクセス可能なドキュメントを取得するには、次の手順を実行します。
ドキュメントの取得
システム変数を使用するには、変数名の先頭に $
を追加します。システム変数 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.
ドキュメントを確認します。
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 } ]
Jane
がアクセス可能なドキュメントを取得するには、次の手順を実行します。
ドキュメントを確認します。
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 } ]
注意
シャーディングされたクラスターでは、ユーザーに代わって別のサーバーノードがシャード上でクエリを実行できます。これらのクエリでは、USER_ROLES
には引き続きユーザーのロールが使用されます。