MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB $setDifference

W MongoDB $setDifference Operator potoku agregacji akceptuje dwa zestawy i wykonuje względne uzupełnienie drugiego zestawu względem pierwszego. Zwraca tablicę zawierającą elementy, które istnieją tylko w pierwszym zestawie.

$setDifference akceptuje dwa argumenty, z których oba mogą być dowolnymi poprawnymi wyrażeniami, o ile każdy z nich rozstrzyga się w postaci tablicy. $setDifference 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ć $setDifference 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: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

{ "a" : [ 1, 2, 3 ], "b" : [ 1, 2, 3 ], "result" : [ ] }
{ "a" : [ 1, 2, 3 ], "b" : [ 1, 2 ], "result" : [ 3 ] }
{ "a" : [ 1, 2 ], "b" : [ 1, 2, 3 ], "result" : [ ] }
{ "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ], "result" : [ 1, 2 ] }
{ "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ], "result" : [ 1, 2, 3 ] }

Zagnieżdżone tablice

$setDifference 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 $setDifference do tych dwóch dokumentów:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 6, 7 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ], "result" : [ 1, 2, 3 ] }
{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ], "result" : [ 1, 2 ] }

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 $setDifference do tych dokumentów:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 8, 9 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

{ "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ], "result" : [ ] }
{ "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ], "result" : [ [ 1, 2, 3 ] ] }

W pierwszym dokumencie a pasuje do b dokładnie, więc wynikiem jest pusta tablica.

W drugim dokumencie zagnieżdżona tablica w a różni się od tablicy zagnieżdżonej w b , a więc cała zagnieżdżona tablica z a jest zwracany.

Brakujące pola

Stosowanie $setDifference do nieistniejącego pola powoduje null .

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 $setDifference do a i b pola:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 10, 11, 12 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

{ "a" : [ 1, 2, 3 ], "result" : null }
{ "b" : [ 1, 2, 3 ], "result" : null }
{ "result" : null }

Niewłaściwy typ danych

Oba operandy $setDifference muszą być tablicami. Jeśli tak nie jest, zgłaszany jest błąd.

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 $setDifference do tych dokumentów:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 13, 14, 15 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "both operands of $setDifference must be arrays. Second argument is of type: double",
	"code" : 17049,
	"codeName" : "Location17049"
} : 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

$setDifference operator odfiltrowuje duplikaty w wyniku, aby wyprowadzić tablicę zawierającą tylko unikalne wpisy. Również kolejność elementów w tablicy wyjściowej jest nieokreślona.

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 $setDifference operator do nich:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setDifference: [ "$a", "$b" ] }
          }
     }
   ]
)

Wynik:

{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2, 3 ], "result" : [ ] }
{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2 ], "result" : [ 3 ] }
{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ ], "result" : [ 1, 2, 3 ] }
{ "a" : [ 3, 2, 1, 2, 3, 1 ], "b" : [ 2, 3, 1 ], "result" : [ ] }
{ "a" : [ 1, 3, 2, 2, 3, 1 ], "b" : [ 2, 1 ], "result" : [ 3 ] }
{ "a" : [ 2, 3, 1, 2, 3, 1 ], "b" : [ ], "result" : [ 2, 3, 1 ] }

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Czy można wielokrotnie wysyłać zapytania do bazy danych MongoDB na żądanie?

  2. Instalacja MongoDB

  3. Utwórz indeks tekstowy symboli wieloznacznych w MongoDB

  4. Agregacja Mongo Dopasuj wiele wartości

  5. Jaki jest najbardziej dojrzały sterownik MongoDB dla C#?