MongoDB включва $strLenBytes
и $strLenCP
оператори в своята рамка на тръбопровода за агрегация. Тези оператори правят подобно, но малко по-различно нещо. В някои случаи и двете ще върнат абсолютно същия резултат, докато в други случаи резултатите ще се различават.
Ето кратък преглед на разликата между тези два оператора.
Разликата
Ето дефиниция на всеки оператор:
$strLenBytes
връща броя на UTF-8 кодирани байтове в посочения низ$strLenCP
връща броя на UTF-8 кодови точки в посочения низ.
Забележете разликата в получер шрифт. Единият връща броя байта , другият връща броя на кодовите точки .
Когато работите с низове на английски, броят на байтовете обикновено ще бъде същият като броя на кодовите точки. Всяка кодова точка ще използва един байт.
Но когато работите с други езици, които използват различен блок Unicode, може да откриете, че броят на байтовете се увеличава до два или три байта. Това е вярно и при работа с други кодови точки на Unicode, като символи, емоджи и т.н. В някои случаи единичен знак може да използва 4 байта.
Пример
Да предположим, че имаме колекция, наречена unicode
със следните документи:
{ "_id" :1, "data" :"é" }{ "_id" :2, "data" :"©" }{ "_id" :3, "data" :"℘" }предварително>И сега нека приложим и двата
$strLenBytes
и$strLenCP
към полето за данни:db.unicode.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Резултат:
{ "data" :"é", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"©", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"℘", "strLenCP" :1, "strLenBytes" :3 }Можем да видим, че всички знаци използват само една кодова точка, но първият документ използва два байта, а другите два документа използват по три байта.
Английски знаци
Да предположим, че имаме колекция, наречена
english
със следните документи:{ "_id" :1, "data" :"Бързо куче" }{ "_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" }И сега нека приложим и двата
$strLenBytes
и$strLenCP
към полето за данни:db.english.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Резултат:
{ "data" :"Бързо куче", "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 }В този случай всички знаци използват по една кодова точка и по един байт.
Тайландски знаци
Ето пример, който използва тайландски знаци, за да демонстрира, че не всички езици използват един байт на кодова точка.
Да предположим, че имаме колекция, наречена
thai
със следните документи:{ "_id" :1, "data" :"ไม้เมือง" }{ "_id" :2, "data" :"ไ" }{ "_id" :3, "data" :"ม้" }{ "_id" :4, "data" :"เ" }{ "_id" :5, "data" :"มื" }{ "_id" :6, "data" :"อ" }{ "_id" :7 , "данни" :"ง" }Ето какво се случва, когато приложим и двата
$strLenBytes
и$strLenCP
към полето за данни:db.thai.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Резултат:
{ "data" :"ไม้เมือง", "strLenCP" :8, "strLenBytes" :24 }{ "data" :"ไ", "strLenCP" :1, "strLenBytes}{ "da" :3 :"ม้", "strLenCP" :2, "strLenBytes" :6 }{ "data" :"เ", "strLenCP" :1, "strLenBytes" :3 }{ "data" :"มื", "strLenCP" :2, "strLenBytes" :6 }{ "data" :"อ", "strLenCP" :1, "strLenBytes" :3 }{ "data" :"ง", "strLenCP" :1, "strLenBytes" :3 }