MongoDB inkluderar $strLenBytes
och $strLenCP
operatörer i dess ramverk för aggregering av pipeline. Dessa operatörer gör en liknande men något annorlunda sak. I vissa fall kommer båda att ge exakt samma resultat, medan resultaten i andra fall skiljer sig åt.
Här är en snabb översikt över skillnaden mellan dessa två operatörer.
Skillnaden
Här är en definition av varje operatör:
$strLenBytes
returnerar antalet UTF-8-kodade byte i den angivna strängen$strLenCP
returnerar antalet UTF-8-kodpunkter i den angivna strängen.
Lägg märke till skillnaden i fetstil. Man returnerar antalet bytes , den andra returnerar antalet kodpunkter .
När man arbetar med strängar på engelska kommer antalet byte vanligtvis att vara detsamma som antalet kodpunkter. Varje kodpunkt kommer att använda en byte.
Men när du arbetar med andra språk som använder ett annat Unicode-block kan du upptäcka att antalet byte ökar till två eller tre byte. Detta gäller även när man arbetar med andra Unicode-kodpunkter som symboler, emoji etc. I vissa fall kan ett enstaka tecken använda 4 byte.
Exempel
Anta att vi har en samling som heter unicode
med följande dokument:
{ "_id" :1, "data" :"é" }{ "_id" :2, "data" :"©" }{ "_id" :3, "data" :"℘" }Och låt oss nu tillämpa båda
$strLenBytes
och$strLenCP
till datafältet: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 att alla tecken bara använder en kodpunkt, men det första dokumentet använder två byte och de andra två dokumenten använder vardera tre byte.
Engelska tecken
Anta att vi har en samling som heter
english
med följande dokument:{ "_id" :1, "data" :"Snabb 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" }Och låt oss nu tillämpa båda
$strLenBytes
och$strLenCP
till datafältet:db.english.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Resultat:
{ "data" :"Snabb 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 det här fallet använder alla tecken en kodpunkt och en byte vardera.
Thailändska tecken
Här är ett exempel som använder thailändska tecken för att visa att inte alla språk använder en byte per kodpunkt.
Anta att vi har en samling som heter
thai
med följande dokument:{ "_id" :1, "data" :"ไม้เมือง" }{ "_id" :2, "data" :"ไ" }{ "_id" :3, "data" :"ม้" }{ "_id" :4, "data" :"เ" }{ "_id" :5, "data" :"มื" }{ "_id" :6, "data" :"อ" }{ "_id" :7 , "data" :"ง" }Det här är vad som händer när vi tillämpar båda
$strLenBytes
och$strLenCP
till datafältet: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 }