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> ] }
Où <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
.