MongoDB inkluderer $strLenBytes og $strLenCP operatører i sin aggregeringspipeline-ramme. Disse operatører gør en lignende, men lidt anderledes ting. I nogle tilfælde vil begge returnere nøjagtigt det samme resultat, mens resultaterne i andre tilfælde vil være forskellige.
Her er et hurtigt overblik over forskellen mellem disse to operatører.
Forskellen
Her er en definition af hver operatør:
$strLenBytesreturnerer antallet af UTF-8-kodede bytes i den angivne streng$strLenCPreturnerer antallet af UTF-8 kodepunkter i den angivne streng.
Bemærk forskellen i fed skrift. Man returnerer antallet bytes , den anden returnerer antallet af kodepunkter .
Når man arbejder med strenge på engelsk, vil antallet af bytes normalt være det samme som antallet af kodepunkter. Hvert kodepunkt vil bruge én byte.
Men når du arbejder med andre sprog, der bruger en anden Unicode-blok, kan du opleve, at antallet af bytes stiger til to eller tre bytes. Dette gælder også, når du arbejder med andre Unicode-kodepunkter såsom symboler, emoji osv. I nogle tilfælde kan et enkelt tegn bruge 4 bytes.
Eksempel
Antag, at vi har en samling kaldet unicode med følgende dokumenter:
{ "_id" :1, "data" :"é" }{ "_id" :2, "data" :"©" }{ "_id" :3, "data" :"℘" }
Og lad os nu anvende begge $strLenBytes og $strLenCP til datafeltet:
db.unicode.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Resultat:
{ "data" :"é", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"©", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"℘", "strLenCP" :1, "strLenBytes" :3 }
Vi kan se, at alle tegn kun bruger ét kodepunkt, men det første dokument bruger to bytes, og de to andre dokumenter bruger hver tre bytes.
Engelske tegn
Antag, at vi har en samling kaldet english med følgende dokumenter:
{ "_id" :1, "data" :"Hurtig hund" }{ "_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" }
Og lad os nu anvende begge $strLenBytes og $strLenCP til datafeltet:
db.english.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Resultat:
{ "data" :"Hurtig hund", "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 }
I dette tilfælde bruger alle tegn et kodepunkt og en byte hver.
Thaiske tegn
Her er et eksempel, der bruger thailandske tegn til at demonstrere, at ikke alle sprog bruger én byte pr. kodepunkt.
Antag, at vi har en samling kaldet thai med følgende dokumenter:
{ "_id" :1, "data" :"ไม้เมือง" }{ "_id" :2, "data" :"ไ" }{ "_id" :3, "data" :"ม้" }{ "_id" :4, "data" :"เ" }{ "_id" :5, "data" :"มื" }{ "_id" :6, "data" :"อ" }{ "_id" :7 , "data" :"ง" }
Her er, hvad der sker, når vi anvender begge $strLenBytes og $strLenCP til datafeltet:
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
strLenCP: { $strLenCP: "$data" },
strLenBytes: { $strLenBytes: "$data" }
}
}
]
)
Resultat:
{ "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 }