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. Lec
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 de2
et3
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 position9
.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 position0
(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 position0
et l'a terminé à la position5
, 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
renvoienull
.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
renvoienull
.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:1Type 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:1Comme l'indique le message d'erreur,
$indexOfBytes requires a string as the first argument
.