sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB $setEquals

I MongoDB, $setEquals aggregeringspipeline-operatör jämför två eller flera arrayer och returnerar true om de har samma distinkta element och false annars.

$setEquals accepterar två eller flera argument, som alla kan vara vilket giltigt uttryck så länge som var och en löser sig till en array. $setEquals behandlar arrayerna som uppsättningar.

Exempel

Anta att vi har en samling som heter data med följande dokument:

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

Vi kan använda $setEquals operatorn mot a och b fält i dessa dokument.

Exempel:

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

Resultat:

{ "a" :[ 1, 2, 3 ], "b" :[ 1, 2, 3 ], "result" :sant }{ "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 ], "resultat " :false }

Inkapslade arrayer

$setEquals operatorn går inte ner i några kapslade arrayer. Den utvärderar bara arrayer på toppnivå.

Anta att vår samling också innehåller följande dokument:

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

Och vi tillämpar $setEquals till dessa två dokument:

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

Resultat:

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

I det första dokumentet, b fältet innehöll en array som bara innehöll ett element – ​​en annan array. I det här fallet utvärderades den yttre arrayen, och den visade sig inte innehålla samma värden som fanns i arrayen vid a .

Men om a fältet hade innehållit en kapslad array i sig, kan det ha varit en annan historia.

Anta att vi har följande dokument:

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

Och vi tillämpar $setEquals till dessa dokument:

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

Resultat:

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

I det första dokumentet, a matchar b exakt, och så resultatet är true .

I det andra dokumentet, den kapslade arrayen vid a skiljer sig från den kapslade arrayen vid b , och så får vi false .

Fält saknas

Använder $setEquals till ett icke-existerande fält resulterar i ett fel.

Tänk på följande dokument:

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

Det första dokumentet har ingen b fältet har det andra dokumentet ingen a och det tredje dokumentet har inte heller.

Det här är vad som händer när vi använder $setEquals till a och b fält:

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

Resultat:

Fel:kommando misslyckades:{ "ok" :0, "errmsg" :"Alla operander av $setEquals måste vara arrayer. Ett argument är av typen:saknas", "code" :17044, "codeName" :"Location17044 "} :aggregat misslyckades :[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@(skal):1:1

Som meddelandet säger måste alla operander vara arrayer. Ett saknat argument/fält är inte en array.

Fel datatyp

Som sett i föregående exempel, alla operander av $setEquals måste vara arrayer. Om fältet de hänvisar till saknas, skapas ett fel. Samma fel uppstår när operanden inte saknas, utan helt enkelt är fel typ.

Anta att vår samling innehåller följande dokument:

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

Och vi tillämpar $setEquals till dessa dokument:

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

Resultat:

Fel:kommando misslyckades:{ "ok" :0, "errmsg" :"Alla operander av $setEquals måste vara arrayer. Ett argument är av typen:double", "code" :17044, "codeName" :"Location17044 "} :aggregat misslyckades :[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@(skal):1:1

Duplicera värden

$setEquals Operatören ignorerar dubbla poster. Den ignorerar också ordningen på elementen.

Anta att vi har följande dokument:

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

Sedan tillämpar vi $setEquals operatör till dem:

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

Resultat:

{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2, 3 ], "result" :sant }{ "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 " :[ ], "resultat" :falskt }

Fler än två argument

Som nämnts, $setEquals accepterar två eller flera argument. I alla fall måste argumenten ha samma distinkta värden för att returnera true . Annars blir resultatet false .

Anta att vi har följande dokument:

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

Dessa dokument har ett extra fält – ett c fältet.

Låt oss nu tillämpa $setEquals till dessa tre fält:

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

Resultat:

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

  1. Hur kör man en Redis-server OCH en annan applikation i Docker?

  2. Redis CLI visar inte nyligen lagrad nyckel via Laravel

  3. Hur får man Redis att välja LRU vräkningspolicy för endast några av nycklarna?

  4. Meteor publicera/prenumerera strategier för unika samlingar på klientsidan