sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB $push vs $addToSet:Jaký je rozdíl?

MongoDB má $push operátor a $addToSet operátor, oba dělají velmi podobnou věc.

Oba operátory připojí hodnoty k existujícímu poli. Hlavní rozdíl je v tom, jak nakládají s poli, která již obsahují hodnotu, kterou se pokoušíte připojit, a také v modifikátorech, které lze použít.

Rozdíly

Stávající hodnoty Pokud již hodnota v poli existuje, $push stále připojí hodnotu (výsledkem budou duplicitní hodnoty).
Nicméně $addToSet pouze připojí hodnotu, pokud již v poli neexistuje. Pokud tedy hodnota již existuje, $addToSet ji nepřipojí (neudělá nic).
Modifikátory $push operátor lze použít s dalšími modifikátory, jako je $sort , $slice a $position , zatímco $addToSet nemůže (alespoň ne od MongoDB 4.4).

Stávající hodnoty

Předpokládejme, že máme sbírku s následujícími dokumenty:

db.players.find()

Výsledek:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5 ] }

Použijme $addToSet pokusit se připojit hodnotu k jednomu z polí.

db.players.update(
   { _id: 3 },
   { $addToSet: { scores: 5 } }
)

Výstup:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

To nám říká, že existoval odpovídající dokument (dokument 3), ale nebyl upraven. Nebyla upravena, protože hodnota, kterou jsme se pokusili vložit (5 ) již v poli existuje.

Podívejme se do sbírky:

db.players.find()

Výsledek:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5 ] }

Podle očekávání se dokument 3 nezměnil.

Zkusme $push místo toho:

db.players.update(
   { _id: 3 },
   { $push: { scores: 5 } }
)

Výstup:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Tentokrát vidíme, že dokument byl upraven.

Můžeme to ověřit opětovnou kontrolou sbírky:

db.products.find()

Výsledek:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5, 5 ] }

Modifikátory

$push operátor lze použít s modifikátory, jako je $position , $sort a $slice .

$addToSet operátor nelze použít s těmito modifikátory.

Zde je to, co se stane, když se pokusím použít tyto modifikátory s $addToSet :

db.players.update(
   { _id: 3 },
   { 
     $addToSet: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Výstup:

WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 2,
		"errmsg" : "Found unexpected fields after $each in $addToSet: { $each: [ 12.0 ], $position: 0.0, $sort: 1.0, $slice: 5.0 }"
	}
})

Chybová zpráva nám říká, že $position , $sort a $slice jsou neočekávaná pole (tj. neměla by tam být).

Zkusme stejné modifikátory s $push :

db.players.update(
   { _id: 3 },
   { 
     $push: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Výstup:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Tentokrát to fungovalo bez chyby.

Ověřte výsledek:

db.players.find()

Výsledek:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5, 5, 12 ] }

Vidíme, že hodnota byla připojena. I když jsme zadali $position: 0 , také jsme zadali $sort: 1 , což znamená, že pole bylo seřazeno poté, co jsme jej umístili.

Také jsme zadali $slice: 5 , který omezil pole na pouhých 5 prvků (což, jak se ukázalo, bylo přesně tolik prvků v poli stejně).


  1. Musím ručně zavřít připojení mongoose?

  2. 7 způsobů, jak zkontrolovat verzi MongoDB

  3. Co je automatické převzetí služeb při selhání NameNode v Hadoop HDFS?

  4. Draft.js – Nelze získat data z databáze. Chyba křížového původu