MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB $setDifference

In MongoDB ist die $setDifference Der Aggregations-Pipeline-Operator akzeptiert zwei Sätze und führt eine relative Ergänzung des zweiten Satzes relativ zum ersten durch. Es gibt ein Array zurück, das die Elemente enthält, die nur in der ersten Menge vorhanden sind.

$setDifference akzeptiert zwei Argumente, die beide ein beliebiger gültiger Ausdruck sein können, solange sie jeweils in ein Array aufgelöst werden. $setDifference behandelt die Arrays als Sets.

Beispiel

Angenommen, wir haben eine Sammlung namens data mit folgenden Dokumenten:

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

Wir können den $setDifference anwenden Operator gegen a und b Felder in diesen Dokumenten.

Beispiel:

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

Ergebnis:

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

Verschachtelte Arrays

Die $setDifference Der Operator steigt nicht in verschachtelte Arrays ab. Es wertet nur Arrays der obersten Ebene aus.

Angenommen, unsere Sammlung enthält auch die folgenden Dokumente:

{ "_id" :6, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :7, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2 ], 3 ] }

Und wir wenden $setDifference an zu diesen beiden Dokumenten:

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

Ergebnis:

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

Im ersten Dokument ist das b field enthielt ein Array, das nur ein Element enthielt – ein weiteres Array. In diesem Fall wurde das äußere Array ausgewertet und es wurde festgestellt, dass es nicht die gleichen Werte enthält wie das Array bei a .

Wenn jedoch a -Feld selbst ein verschachteltes Array enthalten hätte, wäre es vielleicht eine andere Geschichte gewesen.

Angenommen, wir haben die folgenden Dokumente:

{ "_id" :8, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :9, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ] }

Und wir wenden $setDifference an zu diesen Dokumenten:

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

Ergebnis:

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

Im ersten Dokument a entspricht b genau, also ist das Ergebnis ein leeres Array.

Im zweiten Dokument das verschachtelte Array bei a unterscheidet sich von dem verschachtelten Array bei b , und damit das gesamte verschachtelte Array von a zurückgegeben wird.

Fehlende Felder

Anwenden von $setDifference zu einem nicht existierenden Feld ergibt null .

Betrachten Sie die folgenden Dokumente:

{ "_id" :10, "a" :[ 1, 2, 3 ] }{ "_id" :11, "b" :[ 1, 2, 3 ] }{ "_id" :12 } 

Das erste Dokument hat kein b Feld hat das zweite Dokument kein a Feld, und das dritte Dokument hat beides nicht.

Folgendes passiert, wenn wir $setDifference anwenden zum a und b Felder:

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

Ergebnis:

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

Falscher Datentyp

Beide Operanden von $setDifference müssen Arrays sein. Wenn dies nicht der Fall ist, wird ein Fehler ausgegeben.

Angenommen, unsere Sammlung enthält die folgenden Dokumente:

{ "_id" :13, "a" :[ 1, 2, 3 ], "b" :3 }{ "_id" :14, "a" :3, "b" :[ 1, 2, 3 ] }{ "_id" :15, "a" :2, "b" :3 }

Und wir wenden $setDifference an zu diesen Dokumenten:

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

Ergebnis:

nicht erfasste Ausnahme:Fehler:Befehl fehlgeschlagen:{ "ok" :0, "errmsg" :"beide Operanden von $setDifference müssen Arrays sein. Zweites Argument ist vom Typ:double", "code" :17049, "codeName" :"Location17049"} :Aggregat fehlgeschlagen :[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell /assert.js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection .js:1058:12@(shell):1:1

Doppelte Werte

Die $setDifference -Operator filtert Duplikate in seinem Ergebnis heraus, um ein Array auszugeben, das nur eindeutige Einträge enthält. Außerdem ist die Reihenfolge der Elemente im Ausgabearray nicht festgelegt.

Angenommen, wir haben die folgenden Dokumente:

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

Dann wenden wir die $setDifference an Operator zu ihnen:

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

Ergebnis:

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