In MongoDB, il $substrCP
l'operatore della pipeline di aggregazione restituisce la sottostringa di una stringa, in base agli indici del punto di codice UTF-8 specificati.
Sintassi
La sintassi è questa:
{ $substrCP: [ <string expression>, <code point index>, <code point count> ] }
Dove:
<string expression>
è la stringa. Può essere qualsiasi espressione valida purché si risolva in una stringa.<code point index>
è dove iniziare la sottostringa. Può essere qualsiasi espressione valida purché si risolva in un numero intero non negativo.<code point count>
indica per quanti punti di codice deve continuare la sottostringa. Può essere qualsiasi espressione valida purché si risolva in un numero intero non negativo che può essere rappresentato come un intero.
Esempio
Immagina di avere una raccolta chiamata tests
con il seguente documento:
{ "_id" : 1, "data" : "Red Firetruck" }
Possiamo usare $substrCP
così:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 3 ] }
}
}
]
)
Risultato:
{ "data" : "Red Firetruck", "result" : "Red" }
L'indice inizia da zero, quindi la nostra sottostringa è iniziata all'inizio della stringa e ha continuato per tre punti di codice.
In questo caso, utilizziamo caratteri inglesi e ogni carattere ha un punto di codice. Questo ci consente di contare facilmente quanti punti di codice utilizzare.
Facciamo un altro esempio:
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()
Risultato:
{ "data" : "Red Firetruck", "result_1" : "Fire", "result_2" : "truck", "result_3" : "truck" }
Nota nel nostro terzo risultato, abbiamo specificato più punti di codice di quelli disponibili, ma ha semplicemente restituito tutti i caratteri alla fine della stringa.
Segni diacritici
Alcuni caratteri hanno un segno diacritico aggiunto, risultando in più punti di codice.
Supponiamo di avere una collezione chiamata thai
che contiene i seguenti documenti:
{ "_id" : 1, "data" : "ไม้เมือง" } { "_id" : 2, "data" : "ไ" } { "_id" : 3, "data" : "ม้" } { "_id" : 4, "data" : "เ" } { "_id" : 5, "data" : "มื" } { "_id" : 6, "data" : "อ" } { "_id" : 7, "data" : "ง" }
Questi documenti contengono caratteri tailandesi. Possiamo vedere che due di questi caratteri includono un segno diacritico (un piccolo glifo sopra il glifo iniziale).
I documenti da 2 a 7 elencano semplicemente ciascuno dei caratteri che si trovano nel documento 1.
Prima di prendere una sottostringa, scopriamo quanti punti di codice ha ciascuno di questi caratteri usando il $strLenCP
operatore:
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
result: { $strLenCP: "$data" }
}
}
]
)
Risultato:
{ "data" : "ไม้เมือง", "result" : 8 } { "data" : "ไ", "result" : 1 } { "data" : "ม้", "result" : 2 } { "data" : "เ", "result" : 1 } { "data" : "มื", "result" : 2 } { "data" : "อ", "result" : 1 } { "data" : "ง", "result" : 1 }
Possiamo vedere che i due caratteri con i segni diacritici hanno due punti di codice e gli altri hanno un punto di codice.
Applichiamo $substrCP
al primo documento:
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Risultato:
{ "data" : "ไม้เมือง", "result" : "ม้" }
Basato sul nostro punto di partenza di 1
e il nostro conteggio dei punti codice di 2
, otteniamo il secondo carattere e il suo segno diacritico associato.
Separa i Glifi
Nell'esempio precedente il nostro terzo argomento era 2 in modo che restituisse il carattere e il segno diacritico insieme. Ecco cosa succede quando forniamo un terzo argomento di 1.
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 1 ] }
}
}
]
)
Risultato:
{ "data" : "ไม้เมือง", "result" : "ม" }
Il primo carattere viene restituito senza il segno diacritico.
Altri tipi di dati
Il $substrCP
operatore funziona solo su stringhe. Tuttavia, se hai un altro tipo di dati, dovrebbe comunque funzionare, purché possa risolversi in una stringa.
Supponiamo di avere il seguente documento:
{ "_id" : 2, "data" : 123456 }
I data
il campo contiene un numero.
Ecco cosa succede quando applichiamo $substrCP
a quel campo:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Risultato:
{ "data" : 123456, "result" : "23" }
È riuscito a fare bene il lavoro (anche se tieni presente che il risultato è una stringa, non un numero).
Abbiamo un altro documento con un oggetto Date:
{ "_id" : 3, "data" : ISODate("2021-01-03T23:30:15.100Z") }
Ora applichiamo $substrCP
a quel documento:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 4 ] }
}
}
]
)
Risultato:
{ "data" : ISODate("2021-01-03T23:30:15.100Z"), "result" : "2021" }
Quindi ha funzionato bene anche in questo scenario.
Valori Nulli
Se la stringa è null
, il risultato è una stringa vuota.
Supponiamo di avere il seguente documento:
{ "_id" : 4, "data" : null }
Ecco cosa succede quando applichiamo $substrCP
a quel documento:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Risultato:
{ "data" : null, "result" : "" }
Campo mancante
Il tentativo di ottenere una sottostringa da un campo che non esiste restituisce una stringa vuota.
Supponiamo di avere il seguente documento:
{ "_id" : 5 }
Applica $substrCP
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Risultato:
{ "result" : "" }