MongoDB inclui o
$strLenBytes
e $strLenCP
operadores em sua estrutura de pipeline de agregação. Esses operadores fazem uma coisa semelhante, mas um pouco diferente. Em alguns casos, ambos retornarão exatamente o mesmo resultado, enquanto em outros casos os resultados serão diferentes. Aqui está uma rápida visão geral da diferença entre esses dois operadores.
A diferença
Aqui está uma definição de cada operador:
$strLenBytes
retorna o número de bytes codificados em UTF-8 na string especificada$strLenCP
retorna o número de pontos de código UTF-8 na string especificada.
Observe a diferença em negrito. Um retorna o número bytes , o outro retorna o número de pontos de código .
Ao trabalhar com strings em inglês, o número de bytes geralmente será o mesmo que o número de pontos de código. Cada ponto de código usará um byte.
Mas ao trabalhar com outras linguagens que usam um bloco Unicode diferente, você pode descobrir que o número de bytes aumenta para dois ou três bytes. Isso também é verdade ao trabalhar com outros pontos de código Unicode, como símbolos, emoji, etc. Em alguns casos, um único caractere pode usar 4 bytes.
Exemplo
Suponha que tenhamos uma coleção chamada
unicode
com os seguintes documentos:{ "_id" :1, "data" :"é" }{ "_id" :2, "data" :"©" }{ "_id" :3, "data" :"℘" }
E agora vamos aplicar os dois$strLenBytes
e$strLenCP
para o campo de dados:
db.unicode.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Resultado:
{ "data" :"é", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"©", "strLenCP" :1, "strLenBytes" :2 }{ "data" :"℘", "strLenCP" :1, "strLenBytes" :3 }
Podemos ver que todos os caracteres usam apenas um ponto de código, mas o primeiro documento usa dois bytes e os outros dois documentos usam três bytes cada.
Caracteres ingleses
Suponha que tenhamos uma coleção chamadaenglish
com os seguintes documentos:
{ "_id" :1, "data" :"Cachorro rápido" }{ "_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 agora vamos aplicar os dois$strLenBytes
e$strLenCP
para o campo de dados:
db.english.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Resultado:
{ "data" :"Cachorro rápido", "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 }
Nesse caso, todos os caracteres usam um ponto de código e um byte cada.
Personagens tailandeses
Aqui está um exemplo que usa caracteres tailandeses para demonstrar que nem todos os idiomas usam um byte por ponto de código.
Suponha que tenhamos uma coleção chamadathai
com os seguintes documentos:
{ "_id" :1, "data" :"ไม้เมือง" }{ "_id" :2, "data" :"ไ" }{ "_id" :3, "data" :"ม้" }{ "_id" :4, "data" :"เ" }{ "_id" :5, "data" :"มื" }{ "_id" :6, "data" :"อ" }{ "_id" :7 , "dados" :"ง" }
Veja o que acontece quando aplicamos$strLenBytes
e$strLenCP
para o campo de dados:
db.thai.aggregate( [ { $project: { _id: 0, data: 1, strLenCP: { $strLenCP: "$data" }, strLenBytes: { $strLenBytes: "$data" } } } ] )
Resultado:
{ "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 }