Dans MongoDB, le $substrCP
L'opérateur de pipeline d'agrégation renvoie la sous-chaîne d'une chaîne, en fonction des index de points de code UTF-8 spécifiés.
Syntaxe
La syntaxe ressemble à ceci :
{ $substrCP: [ <string expression>, <code point index>, <code point 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.<code point 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 non négatif.<code point count>
est le nombre de points de code 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 $substrCP
comme ceci :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$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 pendant trois points de code.
Dans ce cas, nous utilisons des caractères anglais et chaque caractère a un point de code. Cela nous permet de compter facilement le nombre de points de code à utiliser.
Exécutons un autre exemple :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result_1: { $substrCP: [ "$data", 4, 4 ] },
result_2: { $substrCP: [ "$data", 8, 5 ] },
result_3: { $substrCP: [ "$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 de points de code qu'il n'y en avait de disponibles, mais il a simplement renvoyé tous les caractères à la fin de la chaîne.
Marques diacritiques
Certains caractères ont un signe diacritique ajouté, ce qui entraîne plusieurs points de code.
Supposons que nous ayons une collection appelée thai
qui contient les documents suivants :
{ "_id" : 1, "data" : "ไม้เมือง" } { "_id" : 2, "data" : "ไ" } { "_id" : 3, "data" : "ม้" } { "_id" : 4, "data" : "เ" } { "_id" : 5, "data" : "มื" } { "_id" : 6, "data" : "อ" } { "_id" : 7, "data" : "ง" }
Ces documents contiennent des caractères thaïlandais. Nous pouvons voir que deux de ces caractères incluent un diacritique (un petit glyphe au-dessus du glyphe initial).
Les documents 2 à 7 répertorient simplement chacun des caractères qui se trouvent dans le document 1.
Avant de prendre une sous-chaîne, découvrons combien de points de code chacun de ces caractères a en utilisant le $strLenCP
opérateur :
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
result: { $strLenCP: "$data" }
}
}
]
)
Résultat :
{ "data" : "ไม้เมือง", "result" : 8 } { "data" : "ไ", "result" : 1 } { "data" : "ม้", "result" : 2 } { "data" : "เ", "result" : 1 } { "data" : "มื", "result" : 2 } { "data" : "อ", "result" : 1 } { "data" : "ง", "result" : 1 }
Nous pouvons voir que les deux caractères avec les signes diacritiques ont deux points de code, et les autres ont un point de code.
Appliquons $substrCP
au premier document :
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Résultat :
{ "data" : "ไม้เมือง", "result" : "ม้" }
Basé sur notre point de départ de 1
et notre nombre de points de code de 2
, on obtient le second caractère et son diacritique associé.
Séparez les glyphes
Dans l'exemple précédent, notre troisième argument était 2 afin qu'il renvoie le caractère et le signe diacritique ensemble. Voici ce qui se passe lorsque nous fournissons un troisième argument de 1.
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 1 ] }
}
}
]
)
Résultat :
{ "data" : "ไม้เมือง", "result" : "ม" }
Le premier caractère est renvoyé sans le signe diacritique.
Autres types de données
Le $substrCP
L'opérateur ne fonctionne que sur les chaînes. Cependant, si vous avez un autre type de données, cela devrait toujours fonctionner, tant qu'il peut être résolu en une chaîne.
Supposons que nous ayons le document suivant :
{ "_id" : 2, "data" : 123456 }
Les data
le champ contient un nombre.
Voici ce qui se passe lorsque nous appliquons $substrCP
à ce champ :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Résultat :
{ "data" : 123456, "result" : "23" }
Il a réussi à bien faire le travail (mais gardez à l'esprit que le résultat est une chaîne - pas un nombre).
Nous avons un autre document avec un objet Date :
{ "_id" : 3, "data" : ISODate("2021-01-03T23:30:15.100Z") }
Maintenant, appliquons $substrCP
à ce document :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 4 ] }
}
}
]
)
Résultat :
{ "data" : ISODate("2021-01-03T23:30:15.100Z"), "result" : "2021" }
Cela a donc bien fonctionné dans ce scénario également.
Valeurs nulles
Si la chaîne est null
, le résultat est une chaîne vide.
Supposons que nous ayons le document suivant :
{ "_id" : 4, "data" : null }
Voici ce qui se passe lorsque nous appliquons $substrCP
à ce document :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Résultat :
{ "data" : null, "result" : "" }
Champ manquant
Tenter d'obtenir une sous-chaîne à partir d'un champ qui n'existe pas aboutit à une chaîne vide.
Supposons que nous ayons le document suivant :
{ "_id" : 5 }
Appliquer $substrCP
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Résultat :
{ "result" : "" }