En MongoDB, el $setIsSubset
el operador de canalización de agregación acepta dos matrices y devuelve true
cuando la primera matriz es un subconjunto de la segunda y false
cuando no lo es
La primera matriz también se considera un subconjunto cuando es igual a la segunda matriz.
$setIsSubset
acepta dos argumentos, los cuales pueden ser cualquier expresión válida siempre que se resuelvan en una matriz. $setIsSubset
trata las matrices como conjuntos.
Ejemplo
Supongamos que tenemos una colección llamada data
con los siguientes documentos:
{ "_id" : 1, "a" : [ 1, 2, 3 ], "b" : [ 1, 2, 3 ] } { "_id" : 2, "a" : [ 1, 2, 3 ], "b" : [ 1, 2 ] } { "_id" : 3, "a" : [ 1, 2 ], "b" : [ 1, 2, 3 ] } { "_id" : 4, "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ] } { "_id" : 5, "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ] }
Podemos aplicar el $setIsSubset
operador contra el a
y b
campos en esos documentos.
Ejemplo:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
{ "a" : [ 1, 2, 3 ], "b" : [ 1, 2, 3 ], "result" : true } { "a" : [ 1, 2, 3 ], "b" : [ 1, 2 ], "result" : false } { "a" : [ 1, 2 ], "b" : [ 1, 2, 3 ], "result" : true } { "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ], "result" : false } { "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ], "result" : false }
Matrices anidadas
El $setIsSubset
El operador no desciende a ninguna matriz anidada. Solo evalúa matrices de nivel superior.
Supongamos que nuestra colección también contiene los siguientes documentos:
{ "_id" : 6, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 7, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ] }
Y aplicamos $setIsSubset
a esos dos documentos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ], "result" : false } { "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
En el primer documento, el b
El campo contenía una matriz que contenía solo un elemento:otra matriz. En este caso se encontró que a
no es un subconjunto de b
.
Sin embargo, supongamos que tenemos los siguientes documentos:
{ "_id" : 8, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 9, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ] }
El documento 8 contiene una matriz anidada tanto en el a
y b
campos, y ambas matrices son idénticas.
Esto es lo que sucede cuando aplicamos $setIsSubset
a esos documentos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
{ "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ], "result" : true } { "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
En el primer documento, a
coincide con b
exactamente, por lo que el resultado es true
.
En el segundo documento, a
no es un subconjunto de b
, por lo que el resultado es false
.
Campos faltantes
Aplicando $setIsSubset
a un campo inexistente da como resultado un error.
Considere los siguientes documentos:
{ "_id" : 10, "a" : [ 1, 2, 3 ] } { "_id" : 11, "b" : [ 1, 2, 3 ] } { "_id" : 12 }
El primer documento no tiene una b
campo, el segundo documento no tiene un a
y el tercer documento no tiene ninguno.
Esto es lo que sucede cuando aplicamos $setIsSubset
al a
y b
campos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 10, 11, 12 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
Error: command failed: { "ok" : 0, "errmsg" : "both operands of $setIsSubset must be arrays. Second argument is of type: missing", "code" : 17042, "codeName" : "Location17042" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Tipo de datos incorrecto
Ambos operandos de $setIsSubset
deben ser matrices. Si no lo son, se arroja un error.
Supongamos que nuestra colección contiene los siguientes documentos:
{ "_id" : 13, "a" : [ 1, 2, 3 ], "b" : 3 } { "_id" : 14, "a" : 3, "b" : [ 1, 2, 3 ] } { "_id" : 15, "a" : 2, "b" : 3 }
Y aplicamos $setIsSubset
a esos documentos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 13, 14, 15 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
Error: command failed: { "ok" : 0, "errmsg" : "both operands of $setIsSubset must be arrays. Second argument is of type: double", "code" : 17042, "codeName" : "Location17042" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Valores duplicados
El $setIsSubset
el operador ignora los duplicados. También ignora el orden de los elementos..
Supongamos que tenemos los siguientes documentos:
{ "_id" : 16, "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2, 3 ] } { "_id" : 17, "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2 ] } { "_id" : 18, "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ ] } { "_id" : 19, "a" : [ 3, 2, 1, 2, 3, 1 ], "b" : [ 2, 3, 1 ] } { "_id" : 20, "a" : [ 1, 3, 2, 2, 3, 1 ], "b" : [ 2, 1 ] } { "_id" : 21, "a" : [ 2, 3, 1, 2, 3, 1 ], "b" : [ ] }
Luego aplicamos el $setIsSubset
operador para ellos:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIsSubset: [ "$a", "$b" ] }
}
}
]
)
Resultado:
{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2, 3 ], "result" : true } { "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2 ], "result" : false } { "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ ], "result" : false } { "a" : [ 3, 2, 1, 2, 3, 1 ], "b" : [ 2, 3, 1 ], "result" : true } { "a" : [ 1, 3, 2, 2, 3, 1 ], "b" : [ 2, 1 ], "result" : false } { "a" : [ 2, 3, 1, 2, 3, 1 ], "b" : [ ], "result" : false }