MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Plage de dollars MongoDB

Dans MongoDB, la $range l'opérateur de pipeline d'agrégation renvoie une séquence de nombres générée dans un tableau.

Cette séquence de nombres est basée sur les valeurs d'entrée que vous fournissez.

Syntaxe

La syntaxe ressemble à ceci :

{ $range: [ <start>, <end>, <non-zero step> ] }

<start> est le début et <end> est la fin de la séquence. Chacun d'entre eux peut être n'importe quelle expression valide qui se résout en un entier.

<non-zero step> est un argument facultatif dont la valeur par défaut est 1. Cet argument vous permet de spécifier une valeur d'incrément. S'il est fourni, il doit s'agir d'une expression valide qui se résout en un entier différent de zéro.

Exemple

Supposons que nous ayons une collection appelée range avec les documents suivants :

{ "_id" : 1, "start" : 0, "end" : 5 }
{ "_id" : 2, "start" : 1, "end" : 5 }

Nous pouvons utiliser la $range pour renvoyer un tableau basé sur les valeurs de ces documents.

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            result: { $range: [ "$start", "$end" ] }
          }
     }
   ]
)

Résultat :

{ "start" : 0, "end" : 5, "result" : [ 0, 1, 2, 3, 4 ] }
{ "start" : 1, "end" : 5, "result" : [ 1, 2, 3, 4 ] }

Dans ce cas, nous n'avons pas fourni de troisième argument, et donc $range utilise sa valeur de pas par défaut de 1. Par conséquent, les éléments du tableau sont incrémentés de 1.

Ajouter un incrément explicite

Nous pouvons ajouter un troisième argument pour spécifier explicitement de combien chaque élément du tableau doit être incrémenté.

Supposons que notre collection contienne les documents suivants :

{ "_id" : 3, "start" : 0, "end" : 5, "step" : 1 }
{ "_id" : 4, "start" : 0, "end" : 10, "step" : 2 }
{ "_id" : 5, "start" : 1, "end" : 10, "step" : 2 }
{ "_id" : 6, "start" : 100, "end" : 150, "step" : 10 }

Ces documents ont une step champ, et nous pouvons donc utiliser ce champ pour la valeur d'incrémentation du document respectif.

Maintenant, appliquons $range à ces documents, et incluez l'step champ comme troisième argument :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 3, 4, 5, 6 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            step: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

{ "start" : 0, "end" : 5, "step" : 1, "result" : [ 0, 1, 2, 3, 4 ] }
{ "start" : 0, "end" : 10, "step" : 2, "result" : [ 0, 2, 4, 6, 8 ] }
{ "start" : 1, "end" : 10, "step" : 2, "result" : [ 1, 3, 5, 7, 9 ] }
{ "start" : 100, "end" : 150, "step" : 10, "result" : [ 100, 110, 120, 130, 140 ] }

Valeurs de pas négatives

Le pas peut être une valeur négative, bien que cela doive être fait dans le contexte d'une décrémentation à partir d'un start supérieur numéro à une end inférieure Numéro.

Ajoutons quelques documents supplémentaires à notre collection :

{ "_id" : 7, "start" : 0, "end" : 5, "step" : -1 }
{ "_id" : 8, "start" : 5, "end" : 0, "step" : -1 }
{ "_id" : 9, "start" : 0, "end" : -5, "step" : -1 }

Maintenant, appliquons $range à ces documents :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 7, 8, 9 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            step: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

{ "start" : 0, "end" : 5, "step" : -1, "result" : [ ] }
{ "start" : 5, "end" : 0, "step" : -1, "result" : [ 5, 4, 3, 2, 1 ] }
{ "start" : 0, "end" : -5, "step" : -1, "result" : [ 0, -1, -2, -3, -4 ] }

Nous pouvons voir que le premier document a renvoyé un tableau vide car la valeur de pas négative est en dehors de la plage fournie par le start et end champs.

Cependant, les documents suivants ont produit une plage de valeurs décroissante.

Lorsque le pas est zéro

La valeur du pas doit être un entier différent de zéro. Fournir un pas de 0 renvoie une erreur.

Supposons que nous ajoutions le document suivant à notre collection :

{ "_id" : 10, "start" : 1, "end" : 5, "step" : 0 }

Voici ce qui se passe lorsque nous appliquons $range à ce document :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 10 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$range requires a non-zero step value",
	"code" : 34449,
	"codeName" : "Location34449"
} : 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

Le message d'erreur nous indique explicitement que $range requires a non-zero step value .

Étapes nulles

L'étape ne peut pas être null soit.

Supposons que nous ayons le document suivant :

{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }

Et nous appliquons $range à elle :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 11 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$range requires a numeric step value, found value of type:null",
	"code" : 34447,
	"codeName" : "Location34447"
} : 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

Cela nous indique que $range requires a numeric step value, found value of type:null .

Plages nulles

Si le start et/ou end les champs sont null , une erreur est renvoyée.

Supposons que nous ayons le document suivant :

{ "_id" : 11, "start" : 1, "end" : 5, "step" : null }

Et appliquez $range à elle :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 11 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$range requires a numeric starting value, found value of type: null",
	"code" : 34443,
	"codeName" : "Location34443"
} : 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

Cela nous indique que $range requires a numeric starting value, found value of type: null .

Un message similaire apparaîtrait si la valeur de fin était nulle.

Voici un document avec un null valeur finale :

{ "_id" : 13, "start" : 1, "end" : null, "step" : 1 }

Appliquons $range :

db.range.aggregate(
   [
     { $match: { _id: { $in: [ 13 ] } } },
     {
       $project:
          {
            _id: 0,
            start: 1,
            end: 1,
            result: { $range: [ "$start", "$end", "$step" ] }
          }
     }
   ]
)

Résultat :

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$range requires a numeric ending value, found value of type: null",
	"code" : 34445,
	"codeName" : "Location34445"
} : 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

Cette fois, il nous dit que $range requires a numeric ending value, found value of type: null .