sql >> Database >  >> NoSQL >> MongoDB

MongoDB $setEquals

In MongoDB, de $setEquals aggregatiepijplijnoperator vergelijkt twee of meer arrays en retourneert true als ze dezelfde afzonderlijke elementen hebben en false anders.

$setEquals accepteert twee of meer argumenten, die allemaal elke geldige expressie kunnen zijn, zolang ze elk naar een array worden omgezet. $setEquals behandelt de arrays als sets.

Voorbeeld

Stel dat we een verzameling hebben met de naam data met de volgende documenten:

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

We kunnen de $setEquals . toepassen operator tegen de a en b velden in die documenten.

Voorbeeld:

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

Resultaat:

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

Geneste arrays

De $setEquals operator daalt niet af in geneste arrays. Het evalueert alleen arrays op het hoogste niveau.

Stel dat onze collectie ook de volgende documenten bevat:

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

En we passen $setEquals toe naar die twee documenten:

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

Resultaat:

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

In het eerste document, de b veld bevatte een array die slechts één element bevatte - een andere array. In dit geval is de buitenste array geëvalueerd en bleek deze niet dezelfde waarden te bevatten als in de array op a .

Als de a veld zelf een geneste array had bevat, was het misschien een ander verhaal geweest.

Stel dat we de volgende documenten hebben:

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

En we passen $setEquals toe naar die documenten:

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

Resultaat:

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

In het eerste document, a komt overeen met b precies, en dus is het resultaat true .

In het tweede document, de geneste array op a is anders dan de geneste array op b , en dus krijgen we false .

Ontbrekende velden

$setEquals toepassen naar een niet-bestaand veld resulteert in een fout.

Bekijk de volgende documenten:

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

Het eerste document heeft geen b veld, heeft het tweede document geen a veld, en het derde document heeft geen van beide.

Dit is wat er gebeurt als we $setEquals toepassen naar de a en b velden:

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

Resultaat:

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

Zoals het bericht aangeeft, moeten alle operanden arrays zijn. Een ontbrekend argument/veld is geen array.

Onjuist gegevenstype

Zoals te zien is in het vorige voorbeeld, zijn alle operanden van $setEquals moeten arrays zijn. Als het veld waarnaar ze verwijzen ontbreekt, wordt een fout gegenereerd. Dezelfde fout treedt op wanneer de operand niet ontbreekt, maar gewoon van het verkeerde type is.

Stel dat onze collectie de volgende documenten bevat:

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

En we passen $setEquals toe naar die documenten:

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

Resultaat:

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

Dubbele waarden

De $setEquals operator negeert dubbele vermeldingen. Het negeert ook de volgorde van de elementen.

Stel dat we de volgende documenten hebben:

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

Dan passen we de $setEquals . toe operator voor hen:

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

Resultaat:

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

Meer dan twee argumenten

Zoals vermeld, $setEquals accepteert twee of meer argumenten. In alle gevallen moeten de argumenten dezelfde afzonderlijke waarden hebben om true te retourneren . Anders is het resultaat false .

Stel dat we de volgende documenten hebben:

{ "_id" : 22, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ] }
{ "_id" : 23, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ] }

Deze documenten hebben een extra veld – een c veld.

Laten we nu $setEquals toepassen naar die drie velden:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 22, 23 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            c: 1,
            result: { $setEquals: [ "$a", "$b", "$c" ] }
          }
     }
   ]
)

Resultaat:

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

  1. Op bereik gebaseerde paging mongodb

  2. Mongoose's vindmethode met $or conditie werkt niet goed

  3. Zoek op id met mgo

  4. MongoDB-scherven en ongebalanceerde aggregatieladingen