W MongoDB $setEquals
Operator potoku agregacji porównuje dwie lub więcej tablic i zwraca true
jeśli mają te same odrębne elementy i false
inaczej.
$setEquals
akceptuje co najmniej dwa argumenty, z których wszystkie mogą być dowolnymi prawidłowymi wyrażeniami, pod warunkiem że są one wynikiem tablicy. $setEquals
traktuje tablice jako zestawy.
Przykład
Załóżmy, że mamy kolekcję o nazwie data
z następującymi dokumentami:
{ "_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 ] }
Możemy zastosować $setEquals
operator przed a
i b
pola w tych dokumentach.
Przykład:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
{ "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" : false } { "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ], "result" : false } { "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ], "result" : false }
Zagnieżdżone tablice
$setEquals
operator nie schodzi do żadnych zagnieżdżonych tablic. Ocenia tylko tablice najwyższego poziomu.
Załóżmy, że nasza kolekcja zawiera również następujące dokumenty:
{ "_id" : 6, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 7, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ] }
I stosujemy $setEquals
do tych dwóch dokumentów:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ], "result" : false } { "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
W pierwszym dokumencie b
pole zawierało tablicę, która zawierała tylko jeden element – inną tablicę. W tym przypadku została oceniona tablica zewnętrzna i okazało się, że nie zawiera tych samych wartości, które były w tablicy w a
.
Jeśli jednak a
pole zawierało zagnieżdżoną tablicę, mogła to być inna historia.
Załóżmy, że mamy następujące dokumenty:
{ "_id" : 8, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 9, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ] }
I stosujemy $setEquals
do tych dokumentów:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
{ "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ], "result" : true } { "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
W pierwszym dokumencie a
pasuje do b
dokładnie, więc wynik jest true
.
W drugim dokumencie zagnieżdżona tablica w a
różni się od tablicy zagnieżdżonej w b
, więc otrzymujemy false
.
Brakujące pola
Stosowanie $setEquals
do nieistniejącego pola powoduje błąd.
Rozważ następujące dokumenty:
{ "_id" : 10, "a" : [ 1, 2, 3 ] } { "_id" : 11, "b" : [ 1, 2, 3 ] } { "_id" : 12 }
Pierwszy dokument nie ma b
pole, drugi dokument nie ma a
pole, a trzeci dokument ich nie zawiera.
Oto, co się dzieje, gdy zastosujemy $setEquals
do a
i b
pola:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 10, 11, 12 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
Error: command failed: { "ok" : 0, "errmsg" : "All operands of $setEquals must be arrays. One argument is of type: missing", "code" : 17044, "codeName" : "Location17044" } : 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
Jak stwierdza komunikat, wszystkie operandy muszą być tablicami. Brakujący argument/pole nie jest tablicą.
Niewłaściwy typ danych
Jak widać w poprzednim przykładzie, wszystkie operandy $setEquals
muszą być tablicami. Jeśli brakuje pola, do którego się odnoszą, zgłaszany jest błąd. Ten sam błąd występuje, gdy nie brakuje operandu, ale jest to po prostu niewłaściwy typ.
Załóżmy, że nasza kolekcja zawiera następujące dokumenty:
{ "_id" : 13, "a" : [ 1, 2, 3 ], "b" : 3 } { "_id" : 14, "a" : 3, "b" : [ 1, 2, 3 ] } { "_id" : 15, "a" : 2, "b" : 3 }
I stosujemy $setEquals
do tych dokumentów:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 13, 14, 15 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
Error: command failed: { "ok" : 0, "errmsg" : "All operands of $setEquals must be arrays. One argument is of type: double", "code" : 17044, "codeName" : "Location17044" } : 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
Zduplikowane wartości
$setEquals
operator ignoruje zduplikowane wpisy. Ignoruje również kolejność elementów.
Załóżmy, że mamy następujące dokumenty:
{ "_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" : [ ] }
Następnie stosujemy $setEquals
operator do nich:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Wynik:
{ "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 }
Więcej niż dwa argumenty
Jak wspomniano, $setEquals
akceptuje dwa lub więcej argumentów. We wszystkich przypadkach argumenty muszą mieć te same odrębne wartości, aby zwrócić true
. W przeciwnym razie wynik będzie false
.
Załóżmy, że mamy następujące dokumenty:
{ "_id" : 22, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ] } { "_id" : 23, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ] }
Te dokumenty mają dodatkowe pole – c
pole.
Teraz zastosujmy $setEquals
do tych trzech pól:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 22, 23 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
c: 1,
result: { $setEquals: [ "$a", "$b", "$c" ] }
}
}
]
)
Wynik:
{ "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ], "result" : true } { "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ], "result" : false }