sql >> Base de Datos >  >> NoSQL >> MongoDB

$strLenBytes vs $strLenCP en MongoDB:¿Cuál es la diferencia?

MongoDB incluye el $strLenBytes y $strLenCP operadores en su marco de tubería de agregación. Estos operadores hacen algo similar pero ligeramente diferente. En algunos casos, ambos devolverán exactamente el mismo resultado, mientras que en otros casos los resultados serán diferentes.

Aquí hay una descripción general rápida de la diferencia entre estos dos operadores.

La diferencia

Aquí hay una definición de cada operador:

  • $strLenBytes devuelve el número de bytes codificados en UTF-8 en la cadena especificada
  • $strLenCP devuelve el número de puntos de código UTF-8 en la cadena especificada.

Observe la diferencia en negrita. Uno devuelve el número bytes , el otro devuelve el número de puntos de código .

Cuando se trabaja con cadenas en inglés, el número de bytes suele ser el mismo que el número de puntos de código. Cada punto de código utilizará un byte.

Pero al trabajar con otros idiomas que usan un bloque Unicode diferente, es posible que la cantidad de bytes aumente a dos o tres bytes. Esto también es cierto cuando se trabaja con otros puntos de código Unicode, como símbolos, emoji, etc. En algunos casos, un solo carácter puede usar 4 bytes.

Ejemplo

Supongamos que tenemos una colección llamada unicode con los siguientes documentos:

{ "_id" : 1, "data" : "é" }
{ "_id" : 2, "data" : "©" }
{ "_id" : 3, "data" : "℘" }

Y ahora apliquemos ambos $strLenBytes y $strLenCP al campo de datos:

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 los caracteres usan solo un punto de código, pero el primer documento usa dos bytes y los otros dos documentos usan tres bytes cada uno.

Caracteres en inglés

Supongamos que tenemos una colección llamada english con los siguientes documentos:

{ "_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" }

Y ahora apliquemos ambos $strLenBytes y $strLenCP al campo de datos:

db.english.aggregate(
   [
     {
       $project:
          {
            _id: 0,
            data: 1,
            strLenCP: { $strLenCP: "$data" },
            strLenBytes: { $strLenBytes: "$data" }
          }
     }
   ]
)

Resultado:

{ "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 }

En este caso, todos los caracteres usan un punto de código y un byte cada uno.

Caracteres tailandeses

Aquí hay un ejemplo que usa caracteres tailandeses para demostrar que no todos los idiomas usan un byte por punto de código.

Supongamos que tenemos una colección llamada thai con los siguientes documentos:

{ "_id" : 1, "data" : "ไม้เมือง" }
{ "_id" : 2, "data" : "ไ" }
{ "_id" : 3, "data" : "ม้" }
{ "_id" : 4, "data" : "เ" }
{ "_id" : 5, "data" : "มื" }
{ "_id" : 6, "data" : "อ" }
{ "_id" : 7, "data" : "ง" }

Esto es lo que sucede cuando aplicamos ambos $strLenBytes y $strLenCP al campo de datos:

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 }