Learn the "why" behind slow queries and how to fix them in our 2-Part Webinar.
Register now >
Docs Menu
Docs Home
/ /

$setIntersection (operador de expresión)

$setIntersection

Toma dos o más arreglos y retorna un arreglo que contiene los elementos que aparecen en cada arreglo de entrada.

$setIntersection tiene la siguiente sintaxis:

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

Los argumentos pueden ser cualquier válido. expresión siempre y cuando cada una resuelva a un arreglo. Para obtener más información sobre expresiones, consulta Expresiones.

$setIntersection realiza operaciones de conjunto en arreglos, tratando los arreglos como conjuntos. Si un arreglo contiene entradas duplicadas, $setIntersection ignora las entradas duplicadas. $setIntersection ignora el orden de los elementos.

$setIntersection filtra los duplicados en su resultado para producir un arreglo que contenga solo entradas únicas. El orden de los elementos en el arreglo de salida no está especificado.

Si no se encuentran intersecciones (es decir, los arreglos de entrada no contienen elementos comunes), $setIntersection devuelve un arreglo vacío.

Si un conjunto contiene un elemento de arreglo anidado, $setIntersection no desciende al arreglo anidado, sino que evalúa el arreglo en el nivel superior.

Ejemplo
Resultado
notas
{ $setIntersection: [
[ "a", "c" ],
[ "a", "b" ]
] }
[ "a" ]

El único elemento común entre ambos arreglos es "a".

{ $setIntersection: [
[ "a", "c" ],
[ "a", "b", "c" ]
] }
[ "a", "c" ]

"a" y "c" son elementos comunes entre los dos arreglos.

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

"b" y "a" son elementos comunes entre los dos arreglos.

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

No hay elementos comunes entre las dos matrices. Los elementos de cadena "a" y "b" no son iguales a los de la matriz [ "a", "b" ].

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

No hay elementos comunes entre los dos arreglos, ya que el primer arreglo está vacío.

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

El único elemento común es "a" y aparece una vez en el resultado porque solo se consideran elementos únicos.

Esta sección contiene ejemplos que muestran el uso de $setIntersection con colecciones.

Considere una colección flowers con los siguientes documentos:

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

La siguiente operación usa el operador $setIntersection para devolver un arreglo de elementos comunes tanto al arreglo flowerFieldA como al arreglo flowerFieldB:

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

La operación devuelve los siguientes resultados:

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

A partir de MongoDB 7.0, puedes usar la nueva variable de sistema USER_ROLES para devolver los roles de usuario.

En esta sección aparecen usuarios con varios roles que tienen acceso limitado a documentos en una colección que contiene información presupuestaria.

El escenario muestra un posible uso de USER_ROLES. La colección budget contiene documentos con un campo llamado allowedRoles. Como verás en el siguiente caso, puedes guardar queries que comparen los roles de usuario encontrados en el campo allowedRoles con los roles devueltos por la variable de sistema USER_ROLES.

Nota

Para ver otro ejemplo de USER_ROLES, consulta Recuperación de la información médica para los roles otorgados al usuario actual. Ese ejemplo no almacena los roles de usuario en los campos del documento, tal como se hace en el ejemplo siguiente.

Para el escenario presupuestario de esta sección, realiza los siguientes pasos para crear los roles, usuarios y la colección de budget:

1

Ejecuta:

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

Crea usuarios llamados John y Jane con los roles requeridos. Reemplaza la base de datos test con el nombre de su base de datos.

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

Ejecuta:

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

Realiza los siguientes pasos para recuperar los documentos accesibles a John

1

Ejecuta:

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

Para usar una variable del sistema, agrega $$ al inicio del nombre de la variable. Especifica la variable del sistema USER_ROLES como $$USER_ROLES.

Ejecuta:

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

El ejemplo anterior devuelve los documentos de la colección budget que coinciden con al menos uno de los roles que tiene el usuario que ejecuta el ejemplo. Para hacerlo, el ejemplo utiliza $setIntersection para devolver documentos donde la intersección entre el campo allowedRoles del documento budget y el conjunto de roles de usuario de $$USER_ROLES no está vacía.

3

John tiene los roles Marketing, Operations y Development, y ve estos documentos:

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

Realiza los siguientes pasos para recuperar los documentos accesibles a Jane

1

Ejecuta:

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

Para usar una variable del sistema, agrega $$ al inicio del nombre de la variable. Especifica la variable del sistema USER_ROLES como $$USER_ROLES.

Ejecuta:

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

Jane tiene los roles Sales y Operations y ve estos documentos:

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

Nota

En un clúster, una query se puede ejecutar en un fragmento por otro nodo de servidor en nombre del usuario. En esas queries, USER_ROLES todavía se completan con los roles del usuario.

Volver

$setField

En esta página