sql >> Database >  >> NoSQL >> MongoDB

MongoDB $setIsSubset

In MongoDB, de $setIsSubset aggregatiepijplijnoperator accepteert twee arrays en retourneert true wanneer de eerste array een subset is van de tweede, en false wanneer dat niet het geval is.

De eerste array wordt ook als een subset beschouwd als deze gelijk is aan de tweede array.

$setIsSubset accepteert twee argumenten, die beide elke geldige expressie kunnen zijn, zolang ze elk naar een array worden omgezet. $setIsSubset 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 $setIsSubset . 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: { $setIsSubset: [ "$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" : true }
{ "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ], "result" : false }
{ "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ], "result" : false }

Geneste arrays

De $setIsSubset 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 $setIsSubset toe naar die twee documenten:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 6, 7 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setIsSubset: [ "$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 bleek dat a is geen subset van b .

Veronderstel echter 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 ] }

Document 8 bevat een geneste array op zowel de a en b velden, en beide arrays zijn identiek.

Dit is wat er gebeurt als we $setIsSubset toepassen naar die documenten:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 8, 9 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setIsSubset: [ "$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, a is geen subset van b , en dus is het resultaat false .

Ontbrekende velden

$setIsSubset 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 $setIsSubset toepassen naar de a en b velden:

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

Resultaat:

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

Onjuist gegevenstype

Beide operanden van $setIsSubset moeten arrays zijn. Als dat niet het geval is, wordt er een fout gegenereerd.

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 $setIsSubset toe naar die documenten:

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

Resultaat:

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

Dubbele waarden

De $setIsSubset operator negeert duplicaten. 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 $setIsSubset . toe operator voor hen:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setIsSubset: [ "$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 }

  1. Ingesloten documenteigenschap bijwerken in Mongodb

  2. 'Kon de socketbestandsfout in MongoDB 3.0 niet ontkoppelen'

  3. MongoDB uitvoeren op DigitalOcean

  4. MongoDB - Vraag naar het laatste element van een array?