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

MongoDB $substrBytes

Dans MongoDB, le $substrBytes L'opérateur de pipeline d'agrégation renvoie la sous-chaîne d'une chaîne, en fonction des index d'octets codés UTF-8 spécifiés.

Syntaxe

La syntaxe ressemble à ceci :

{ $substrBytes: [ <string expression>, <byte index>, <byte count> ] }

Où :

  • <string expression> est la chaîne. Il peut s'agir de n'importe quelle expression valide tant qu'elle se résout en une chaîne.
  • <byte index> est où commencer la sous-chaîne. Il peut s'agir de n'importe quelle expression valide tant qu'elle se résout en un entier ou un nombre non négatif pouvant être représenté sous la forme d'un entier.
  • <byte count> est le nombre d'octets pendant lesquels la sous-chaîne doit continuer. Il peut s'agir de n'importe quelle expression valide tant qu'elle se résout en un entier ou un nombre non négatif pouvant être représenté sous la forme d'un entier.

Exemple

Imaginez que nous ayons une collection appelée tests avec le document suivant :

{ "_id" : 1, "data" : "Red Firetruck" }

Nous pouvons utiliser $substrBytes comme ceci :

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

Résultat :

{ "data" : "Red Firetruck", "result" : "Red" }

L'index commence à zéro, et donc notre sous-chaîne a commencé au début de la chaîne et s'est poursuivie sur trois octets.

Dans ce cas, nous utilisons des caractères anglais et chaque caractère est un octet. Cela nous permet de compter facilement le nombre d'octets à utiliser.

Exécutons un autre exemple :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result_1: { $substrBytes: [ "$data", 4, 4 ] },
            result_2: { $substrBytes: [ "$data", 8, 5 ] },
            result_3: { $substrBytes: [ "$data", 8, 20 ] }
          }
     }
   ]
).pretty()

Résultat :

{
	"data" : "Red Firetruck",
	"result_1" : "Fire",
	"result_2" : "truck",
	"result_3" : "truck"
}

Remarquez que dans notre troisième résultat, nous avons spécifié plus d'octets qu'il n'y en avait de disponibles, mais il a simplement renvoyé tous les caractères à la fin de la chaîne.

Caractères multi-octets

Certains caractères utilisent plus d'un octet. Certains en utilisent deux, d'autres en utilisent trois et d'autres en utilisent même quatre.

Voici un exemple de document contenant un tas de symboles :

{ "_id" : 2, "data" : "©♡★✪☆" }

Chacun de ces caractères utilise plus d'un octet. Cela signifie que nous devons être prudents lors de l'extraction d'une sous-chaîne. Nous devons être sûrs que notre point de départ ne commence pas à mi-chemin d'un personnage. Si c'est le cas, une erreur se produira. De même, nous devons nous assurer que notre point final ne se termine pas à mi-chemin d'un personnage.

Pour l'instant, appliquons $substrBytes sans effectuer d'erreur :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 2 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            bytes: { $strLenBytes: [ "$data" ] },
            result: { $substrBytes: [ "$data", 0, 5 ] }
          }
     }
   ]
)

Résultat :

{ "data" : "©♡★✪☆", "bytes" : 14, "result" : "©♡" }

Basé sur notre point de départ de 0 et notre longueur en octets de 5 , nous obtenons deux caractères dans notre jeu de résultats. Nous pouvons donc voir que les deux premiers caractères utilisent 5 octets.

Dans cet exemple, j'ai également utilisé $strLenBytes pour renvoyer le nombre total d'octets dans la chaîne. J'ai fait cela principalement pour montrer que les cinq caractères utilisent 14 octets (plusieurs octets par caractère).

Voici un exemple légèrement modifié qui renvoie chacun des deux caractères renvoyés :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 2 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            r1: { $substrBytes: [ "$data", 0, 2 ] },
            r2: { $substrBytes: [ "$data", 2, 3 ] }
          }
     }
   ]
)

Résultat :

{ "data" : "©♡★✪☆", "r1" : "©", "r2" : "♡" }

Nous pouvons voir que le premier caractère utilise deux octets et le deuxième caractère en utilise trois.

Mauvais point de départ

Si votre point de départ est à mi-chemin d'un caractère, une erreur se produit.

Exemple :

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

Résultat :

Error: command failed: {
	"ok" : 0,
	"errmsg" : "$substrBytes:  Invalid range, starting index is a UTF-8 continuation byte.",
	"code" : 28656,
	"codeName" : "Location28656"
} : 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 erreur nous indique que l'index starting index is a UTF-8 continuation byte . En d'autres termes, nous avons essayé de commencer à mi-chemin d'un personnage.

Mauvais point final

C'est la même chose avec le point final. Si votre point final est à mi-chemin d'un caractère, une erreur se produit.

Exemple :

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

Résultat :

Error: command failed: {
	"ok" : 0,
	"errmsg" : "$substrBytes:  Invalid range, ending index is in the middle of a UTF-8 character.",
	"code" : 28657,
	"codeName" : "Location28657"
} : 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 indique que l'index de fin ending index is in the middle of a UTF-8 character .