$setIntersection(集計)
定義
$setIntersection
2 つ以上の配列を受け取り、すべての入力配列に現れる要素を含む配列を返します。
$setIntersection
の構文は次のとおりです。{ $setIntersection: [ <array1>, <array2>, ... ] } 引数は、それぞれが配列に変換される限り、有効な式であれば何でも使用できます。 式の詳細については、「式演算子 」を参照してください。
動作
$setIntersection
は、配列をセットとして扱い、配列に対してセット演算を実行します。 配列に重複エントリが含まれている場合、 $setIntersection
は重複エントリを無視します。 $setIntersection
は要素の順序を無視します。
$setIntersection
は結果内の重複を除外して、一意のエントリのみを含む配列を出力します。 出力配列内の要素の順序は指定されていません。
共通要素が見つからない場合(入力配列に共通要素が含まれていない場合)、 $setIntersection
は空の配列を返します。
セットにネストされた配列要素が含まれている場合、 $setIntersection
はネストされた配列に下降 せず、最上位の配列を評価します。
例 | 結果 | ||
---|---|---|---|
|
| ||
|
|
例
このセクションでは、 コレクションで$setIntersection
を使用していることを示す例えが含まれています。
要素配列の例
以下のドキュメントを持つ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
システム変数を使用してユーザー ロールを返すことができます。
このセクションのシナリオでは、予算情報を含むコレクション内のドキュメントへのアクセスが制限されているさまざまなロールを持つユーザーを示します。
このシナリオでは、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" ] }, [] ] } } } } ] )
前の例では、 budget
コレクションから、この例を実行するユーザーが持っているロールの少なくとも 1 つと一致するドキュメントが返されます。 そのために、この例では$setIntersection
を使用して、 budget
ドキュメントallowedRoles
フィールドと$$USER_ROLES
のユーザー ロールのセットの共通部分が空ではないドキュメントを返します。
ドキュメントを確認します。
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
には引き続きユーザーのロールが使用されます。