MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $bsonSize

Da MongoDB 4.4, puoi usare $bsonSize operatore della pipeline di aggregazione per restituire la dimensione di un determinato documento in byte.

$bsonSize accetta qualsiasi espressione valida purché si risolva in un oggetto o in null .

Esempio

Supponiamo di avere una collezione chiamata bars con il seguente documento:

{
	"_id" : 1,
	"name" : "Boardwalk Social",
	"location" : {
		"type" : "Point",
		"coordinates" : [
			-16.919297718553366,
			145.77675259719823
		]
	},
	"categories" : [
		"Bar",
		"Restaurant",
		"Hotel"
	],
	"reviews" : [
		{
			"name" : "Steve",
			"date" : "20 December, 2020",
			"rating" : 5,
			"comments" : "Great vibe."
		},
		{
			"name" : "Lisa",
			"date" : "25 October, 2020",
			"rating" : 3,
			"comments" : "They just raised their prices :("
		},
		{
			"name" : "Kim",
			"date" : "21 October, 2020",
			"rating" : 4,
			"comments" : "Nice for Friday happy hour"
		}
	]
}

Possiamo vedere che la location campo contiene un documento. E le reviews contiene un array di documenti.

Usiamo il $bsonSize operatore per verificare la dimensione della location campo:

db.bars.aggregate([
  {
    $project: {
      "locationSize": { $bsonSize: "$location" }
    }
  }
])

Risultato:

{ "_id" : 1, "locationSize" : 61 }

In questo caso, la dimensione della location il campo è 61 byte.

Oggetti negli array

Ecco un esempio di come ottenere le dimensioni di un documento che è un elemento di un array:

db.bars.aggregate([
  {
    $project: {
      "review": { $arrayElemAt: [ "$reviews", 0 ] },
      "reviewSize": { $bsonSize: { $arrayElemAt: [ "$reviews", 0 ] } }
    }
  }
]).pretty()

Risultato:

{
	"_id" : 1,
	"review" : {
		"name" : "Steve",
		"date" : "20 December, 2020",
		"rating" : 5,
		"comments" : "Great vibe."
	},
	"reviewSize" : 91
}

In questo caso, utilizziamo $arrayElemAt per restituire la recensione effettiva, e poi di nuovo per restituire la dimensione di quella recensione.

Gli array MongoDB sono a base zero, quindi la recensione è la prima.

Ottieni la dimensione del documento di primo livello

Possiamo usare il $$ROOT variabile di sistema per fare riferimento al documento di livello superiore o al documento radice. Questo è il documento attualmente in fase di elaborazione da parte della pipeline.

Pertanto, possiamo passare il $$ROOT variabile a $bsonSize per ottenere le dimensioni dell'intero documento attualmente in elaborazione.

Esempio:

db.bars.aggregate([
  {
    $project: {
      "rootSize": { $bsonSize: "$$ROOT" }
    }
  }
])

Risultato:

{ "_id" : 1, "rootSize" : 502 }

In questo caso, il documento è di 502 byte.

Tipi di dati errati

Come accennato, $bsonSize accetta qualsiasi espressione valida purché si risolva in un oggetto o null .

Ecco un esempio di cosa succede se fornisci un'espressione che si risolve in un tipo BSON diverso:

db.bars.aggregate([
  {
    $project: {
      "nameSize": { $bsonSize: "$name" }
    }
  }
])

Risultato:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "$bsonSize requires a document input, found: string",
	"code" : 31393,
	"codeName" : "Location31393"
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:618:17
[email protected]/mongo/shell/assert.js:708:16
[email protected]/mongo/shell/db.js:266:5
[email protected]/mongo/shell/collection.js:1046:12
@(shell):1:1

In questo caso, abbiamo provato a trovare la dimensione di una stringa, ma non è uno dei tipi BSON supportati, quindi otteniamo un errore.

Tuttavia, non tutto è perduto. Possiamo usare $binarySize per ottenere la dimensione di una stringa.

Ottieni la dimensione totale di tutti i documenti in una raccolta

Supponiamo di avere una collezione chiamata cats con i seguenti documenti:

{ "_id" : 1, "name" : "Scratch", "born" : "March, 2020" }
{ "_id" : 2, "name" : "Meow", "weight" : 30 }
{ "_id" : 3, "name" : "Fluffy", "height" : 15 }
{ "_id" : 4, "name" : "Sox", "weight" : 40 }
{ "_id" : 5, "name" : null, "weight" : 20 }
{ "_id" : 6, "height" : 20, "born" : ISODate("2021-01-03T23:30:15.123Z") }

Come mostrato in precedenza, possiamo utilizzare $$ROOT per restituire il documento di primo livello attualmente in elaborazione:

db.cats.aggregate([
  {
    $project: {
      "rootSize": { $bsonSize: "$$ROOT" }
    }
  }
])

Risultato:

{ "_id" : 1, "rootSize" : 58 }
{ "_id" : 2, "rootSize" : 49 }
{ "_id" : 3, "rootSize" : 51 }
{ "_id" : 4, "rootSize" : 48 }
{ "_id" : 5, "rootSize" : 40 }
{ "_id" : 6, "rootSize" : 48 }

Ma possiamo anche ottenere il totale dimensione di tutti i documenti della collezione.

Possiamo raggiungere questo obiettivo come segue:

db.cats.aggregate([
  {
    $group: {
      "_id": null,
      "rootSize": { $sum: { $bsonSize: "$$ROOT" } }
    }
  }
])

Risultato:

{ "_id" : null, "rootSize" : 294 }

Qui, abbiamo raggruppato i risultati usando il $group operatore e fornendo un _id di null . Avremmo potuto utilizzare qualsiasi altro valore costante.

Abbiamo anche usato $sum per calcolare le dimensioni combinate dei vari documenti.

Possiamo vedere che la dimensione totale di tutti i documenti nella raccolta è 294, che possiamo confermare sommando i risultati nell'esempio precedente.

Metodo Object.bsonSize()

Un altro modo per ottenere le dimensioni di un documento è utilizzare Object.bsonSize() metodo.