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

MongoDB $indexOfArray

Dans MongoDB, le $indexOfArray L'opérateur de pipeline d'agrégation recherche dans un tableau une occurrence d'une valeur spécifiée et renvoie l'index de tableau de la première occurrence.

Syntaxe

La syntaxe ressemble à ceci :

{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }

Où :

  • <array expression> est le tableau à rechercher.
  • <search expression> est la valeur que vous voulez trouver dans le tableau.
  • <start> est un argument facultatif qui spécifie un point de départ à rechercher dans le tableau. Il peut s'agir de n'importe quelle expression valide qui se résout en un nombre entier non négatif.
  • <end> est un argument facultatif qui spécifie une position d'index de fin pour la recherche. Il peut s'agir de n'importe quelle expression valide qui se résout en un nombre entier non négatif.

Dans MongoDB, les tableaux sont basés sur zéro, donc le nombre d'index commence à zéro (0 ).

Si la valeur spécifiée n'est pas trouvée, $indexOfArray renvoie -1 .

S'il existe plusieurs instances de la valeur spécifiée, seule la première est renvoyée.

Exemple

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

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "XS", "M", "L" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "XS", "S", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "XXS", "XS", "M", "XL" ] }
{ "_id" : 4, "prod" : "Zap", "sizes" : [ 10, 12, 15 ] }
{ "_id" : 5, "prod" : "Tap", "sizes" : [ 15, 16, 20 ] }

Voici un exemple d'application de $indexOfArray à ces documents :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ "XS", "M", "L" ], "result" : 0 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }
{ "sizes" : [ 10, 12, 15 ], "result" : -1 }
{ "sizes" : [ 15, 16, 20 ], "result" : -1 }

Dans les deux premiers documents, la valeur de recherche a été trouvée à la position 0 (les tableaux sont basés sur zéro).

Dans le troisième document, il a été trouvé à la position 1 . Notez que la recherche portait sur une correspondance exacte. Il n'a pas renvoyé la position 0 , même si la valeur à la position 0 contient la valeur de recherche (c'est-à-dire XXS contient XS ).

La valeur de recherche n'a pas été trouvée dans les deux derniers documents, et donc -1 a été renvoyé.

Voici un autre exemple, sauf que cette fois nous recherchons une valeur numérique :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", 15 ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ "XS", "M", "L" ], "result" : -1 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
{ "sizes" : [ 10, 12, 15 ], "result" : 2 }
{ "sizes" : [ 15, 16, 20 ], "result" : 0 }

Spécifiez une position de départ

Vous pouvez fournir un troisième argument pour spécifier une position d'index de départ pour la recherche.

Exemple :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", 15, 1 ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ 10, 12, 15 ], "result" : 2 }
{ "sizes" : [ 15, 16, 20 ], "result" : -1 }

Dans ce cas, l'expression de recherche n'a pas été trouvée dans le deuxième document (document 5). C'est parce que nous avons commencé la recherche à la position 1 , et bien que ce document contienne l'expression de recherche, il se trouve à la position 0 (avant la position de départ de la recherche).

Spécifiez une position de fin

Vous pouvez également fournir un quatrième argument pour spécifier la position d'index de fin pour la recherche.

Si vous fournissez cet argument, vous devez également fournir une position de départ. Si vous ne le faites pas, cet argument sera interprété comme le point de départ.

Exemple :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ "XS", "M", "L" ], "result" : 0 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }

Le troisième document a renvoyé -1 ce qui signifie que l'expression de recherche n'a pas été trouvée.

Voici ce qui se passe si nous incrémentons la position d'index de fin de 1 :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ "XS", "M", "L" ], "result" : 0 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }

Cette fois, la valeur a été incluse et sa position d'index a été renvoyée.

Tableaux vides

La recherche d'un tableau vide renvoie -1 .

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ ], "result" : -1 }

Champs manquants

Si le champ n'est pas dans le document, $indexOfArray renvoie null .

Supposons que nous ayons le document suivant :

{ "_id" : 8, "prod" : "Map" }

Voici ce qui se passe lorsque nous appliquons $indexOfArray :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 8 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Résultat :

{ "result" : null }

Valeurs nulles

Si l'expression du tableau est null (au lieu d'un tableau), $indexOfArray renvoie null .

Supposons que nous ayons le document suivant :

{ "_id" : 7, "prod" : "Lap", "sizes" : null }

Voici ce qui se passe lorsque nous appliquons $indexOfArray :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 7 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : null, "result" : null }

Cependant, lorsque l'expression de recherche est null , le résultat est -1 , sauf si l'expression de tableau est également null ou son champ est manquant :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", null ] }
          }
     }
   ]
)

Résultat :

{ "sizes" : [ "XS", "M", "L" ], "result" : -1 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
{ "sizes" : [ 10, 12, 15 ], "result" : -1 }
{ "sizes" : [ 15, 16, 20 ], "result" : -1 }
{ "sizes" : [ ], "result" : -1 }
{ "sizes" : null, "result" : null }
{ "result" : null }

Type de données incorrect

Si l'expression de tableau est le mauvais type de données, $indexOfArray renvoie une erreur.

Supposons que nous ayons le document suivant :

{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }

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

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 9 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XXL" ] }
          }
     }
   ]
)

Résultat :

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfArray requires an array as a first argument, found: string",
	"code" : 40090,
	"codeName" : "Location40090"
} : 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

Comme l'indique le message d'erreur, $indexOfArray requires an array as a first argument .