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

MongoDB $indexOfBytes

Dans MongoDB, le $indexOfBytes L'opérateur de pipeline d'agrégation recherche dans une chaîne une occurrence d'une sous-chaîne et renvoie l'index d'octets UTF-8 de la première occurrence.

L'index d'octets UTF est basé sur zéro (c'est-à-dire qu'il commence à 0 ).

Syntaxe

La syntaxe ressemble à ceci :

{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] } 

Où :

  • <string expression> est la chaîne à rechercher.
  • <substring expression> est la sous-chaîne que vous souhaitez rechercher dans la chaîne.
  • <start> est un argument facultatif qui spécifie une position d'index de départ pour la recherche. 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.

Si la valeur spécifiée est introuvable, $indexOfBytes 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 test avec les documents suivants :

{ "_id" :1, "data" :"c 2021" }{ "_id" :2, "data" :"© 2021" }{ "_id" :3, "data" :"ไม้เมือง" } 

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

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "2021" ] }
          }
     }
   ]
) 

Résultat :

{ "data" :"c 2021", "result" :2 }{ "data" :"© 2021", "result" :3 }{ "data" :"ไม้เมือง", "result" :- 1 } 

Nous pouvons voir que les deux premiers documents ont produit des résultats différents, même si la sous-chaîne semble être dans la même position pour chaque document. Dans le premier document, la sous-chaîne a été trouvée à la position d'index d'octet 2 , alors que le deuxième document l'avait à 3 .

La raison en est que le symbole de copyright (© ) dans le second document occupe 2 octets. Le c caractère (dans le premier document) utilise seulement 1 octet. Le caractère espace utilise également 1 octet.

Le résultat de $indexOfBytes est de base zéro (l'index commence à 0 ), et nous nous retrouvons donc avec un résultat de 2 et 3 respectivement.

Concernant le troisième document, la sous-chaîne n'a pas été trouvée du tout, et le résultat est donc -1 .

Voici un autre exemple, sauf que cette fois nous recherchons un caractère thaï :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "เ" ] }
          }
     }
   ]
) 

Résultat :

{ "data" :"c 2021", "result" :-1 }{ "data" :"© 2021", "result" :-1 }{ "data" :"ไม้เมือง", "result" :9 }

Dans ce cas, nous avons recherché un caractère qui apparaît en troisième position dans le troisième document, et son index d'octets UTF-8 revient sous la forme 9 .

En effet, dans ce cas, chaque caractère utilise 3 octets. Mais le deuxième caractère a un signe diacritique, qui est également de 3 octets. Par conséquent, les deux premiers caractères (y compris le diacritique) utilisent 9 octets. Compte tenu de l'indexation à base zéro, leurs index d'octets UTF-8 vont de 0 à 8 . Cela signifie que le troisième caractère commence à la position 9 .

Voir MongoDB $strLenBytes pour un exemple qui renvoie le nombre d'octets pour chaque caractère dans cette chaîne particulière.

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.

Supposons que nous ayons le document suivant :

{ "_id" :4, "data" :"ABC XYZ ABC" }

Voici un exemple d'application de $indexOfBytes avec une position de départ :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
          }
     }
   ]
) 

Résultat :

{ "data" :"ABC XYZ ABC", "result" :8 }

Dans ce cas, la deuxième instance de la sous-chaîne a été renvoyée. C'est parce que nous avons commencé la recherche à la position 1 , et la première instance de la sous-chaîne commence à la position 0 (avant la position de départ de la recherche).

Si la position de début est un nombre supérieur à la longueur en octets de la chaîne ou supérieur à la position de fin, $indexOfBytes renvoie -1 .

S'il s'agit d'un nombre négatif, $indexOfBytes renvoie une erreur.

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.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
          }
     }
   ]
) 

Résultat :

{ "data" :"ABC XYZ ABC", "result" :-1 }

Le résultat est -1 ce qui signifie que la sous-chaîne n'a pas été trouvée. C'est parce que nous avons commencé notre recherche à la position 0 et l'a terminé à la position 5 , donc ne capturant pas la sous-chaîne.

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

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
          }
     }
   ]
) 

Résultat :

{ "data" :"ABC XYZ ABC", "result" :4 }

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

Si la position de fin est un nombre inférieur à la position de départ, $indexOfBytes renvoie -1 .

S'il s'agit d'un nombre négatif, $indexOfBytes renvoie une erreur.

Champs manquants

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

Supposons que nous ayons le document suivant :

{ "_id" :5 }

Voici ce qui se passe lorsque nous appliquons $indexOfBytes :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 5 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
) 

Résultat :

{ "résultat" :nul }

Valeurs nulles

Si le premier argument est null , $indexOfBytes renvoie null .

Supposons que nous ayons le document suivant :

{ "_id" :6, "data" :null }

Voici ce qui se passe lorsque nous appliquons $indexOfBytes :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
) 

Résultat :

{ "data" :null, "result" :null }

Cependant, lorsque le deuxième argument (c'est-à-dire la sous-chaîne) est null , une erreur est renvoyée :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", null ] }
          }
     }
   ]
) 

Résultat :

exception non détectée :erreur :échec de la commande :{ "ok" :0, "errmsg" :"$indexOfBytes nécessite une chaîne comme deuxième argument, trouvé : null", "code" :40092, "codeName" :"Location40092 "} :l'agrégat a échoué :[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell/assert. js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection.js :1058:12@(shell):1:1

Type de données incorrect

Si le premier argument est le mauvais type de données (c'est-à-dire qu'il ne se résout pas en chaîne), $indexOfBytes renvoie une erreur.

Supposons que nous ayons le document suivant :

{ "_id" :7, "données" :123 }

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

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 7 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
) 

Résultat :

exception non détectée :erreur :échec de la commande :{ "ok" :0, "errmsg" :"$indexOfBytes nécessite une chaîne comme premier argument, trouvé :double", "code" :40091, "codeName" :"Location40091 "} :l'agrégat a échoué :[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell/assert. js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection.js :1058:12@(shell):1:1

Comme l'indique le message d'erreur, $indexOfBytes requires a string as the first argument .