MongoDB include $strLenBytes
e $strLenCP
operatori nel suo quadro di pipeline di aggregazione. Questi operatori fanno una cosa simile ma leggermente diversa. In alcuni casi, entrambi restituiranno esattamente lo stesso risultato, mentre in altri casi i risultati saranno diversi.
Ecco una rapida panoramica della differenza tra questi due operatori.
La differenza
Ecco una definizione di ciascun operatore:
$strLenBytes
restituisce il numero di byte codificati UTF-8 nella stringa specificata$strLenCP
restituisce il numero di punti di codice UTF-8 nella stringa specificata.
Notare la differenza in grassetto. Uno restituisce il numero byte , l'altro restituisce il numero di punti di codice .
Quando si lavora con stringhe in inglese, il numero di byte sarà solitamente lo stesso del numero di punti di codice. Ciascun punto di codice utilizzerà un byte.
Ma quando si lavora con altre lingue che utilizzano un blocco Unicode diverso, è possibile che il numero di byte aumenti a due o tre byte. Questo vale anche quando si lavora con altri punti di codice Unicode come simboli, emoji, ecc. In alcuni casi un singolo carattere potrebbe utilizzare 4 byte.
Esempio
Supponiamo di avere una collezione chiamata unicode
con i seguenti documenti:
{ "_id" : 1, "data" : "é" } { "_id" : 2, "data" : "©" } { "_id" : 3, "data" : "℘" }
E ora applichiamo entrambi $strLenBytes
e $strLenCP
al campo dati:
db.unicode.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Risultato:
{ "data" : "é", "strLenCP" : 1, "strLenBytes" : 2 } { "data" : "©", "strLenCP" : 1, "strLenBytes" : 2 } { "data" : "℘", "strLenCP" : 1, "strLenBytes" : 3 }
Possiamo vedere che tutti i caratteri utilizzano un solo punto di codice, ma il primo documento utilizza due byte e gli altri due documenti utilizzano ciascuno tre byte.
Caratteri inglesi
Supponiamo di avere una collezione chiamata english
con i seguenti documenti:
{ "_id" : 1, "data" : "Fast dog" } { "_id" : 2, "data" : "F" } { "_id" : 3, "data" : "a" } { "_id" : 4, "data" : "s" } { "_id" : 5, "data" : "t" } { "_id" : 6, "data" : " " } { "_id" : 7, "data" : "d" } { "_id" : 8, "data" : "o" } { "_id" : 9, "data" : "g" }
E ora applichiamo entrambi $strLenBytes
e $strLenCP
al campo dati:
db.english.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Risultato:
{ "data" : "Fast dog", "strLenCP" : 8, "strLenBytes" : 8 } { "data" : "F", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "a", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "s", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "t", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : " ", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "d", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "o", "strLenCP" : 1, "strLenBytes" : 1 } { "data" : "g", "strLenCP" : 1, "strLenBytes" : 1 }
In questo caso, tutti i caratteri utilizzano un punto di codice e un byte ciascuno.
Personaggi tailandesi
Ecco un esempio che utilizza caratteri tailandesi per dimostrare che non tutte le lingue utilizzano un byte per punto di codice.
Supponiamo di avere una collezione chiamata thai
con i seguenti documenti:
{ "_id" : 1, "data" : "ไม้เมือง" } { "_id" : 2, "data" : "ไ" } { "_id" : 3, "data" : "ม้" } { "_id" : 4, "data" : "เ" } { "_id" : 5, "data" : "มื" } { "_id" : 6, "data" : "อ" } { "_id" : 7, "data" : "ง" }
Ecco cosa succede quando applichiamo entrambi $strLenBytes
e $strLenCP
al campo dati:
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Risultato:
{ "data" : "ไม้เมือง", "strLenCP" : 8, "strLenBytes" : 24 } { "data" : "ไ", "strLenCP" : 1, "strLenBytes" : 3 } { "data" : "ม้", "strLenCP" : 2, "strLenBytes" : 6 } { "data" : "เ", "strLenCP" : 1, "strLenBytes" : 3 } { "data" : "มื", "strLenCP" : 2, "strLenBytes" : 6 } { "data" : "อ", "strLenCP" : 1, "strLenBytes" : 3 } { "data" : "ง", "strLenCP" : 1, "strLenBytes" : 3 }