BSON es un formato de serialización binaria que se utiliza para almacenar documentos y realizar llamadas a procedimientos remotos en MongoDB. La especificación de BSON se encuentra en bsonspec.org.
Cada tipo de BSON tiene identificadores tanto enteros como de strings, como se enumeran en la siguiente tabla:
Tipo | Número | Alias | notas |
|---|---|---|---|
Double | 1 | "double" | |
String | 2 | "string" | |
Objeto | 3 | "objeto" | |
Arreglo | 4 | "arreglo" | |
Datos binarios | 5 | "binData" | |
Indefinido | 6 | "indefinido" | Obsoleto. |
ObjectId | 7 | "objectId" | |
Booleano | 8 | "bool" | |
fecha | 9 | "date" | |
Nulo | 10 | "null" | |
Expresión regular | 11 | "regex" | |
DBPointer | 12 | "dbPointer" | Obsoleto. |
JavaScript | 13 | "javascript" | |
Símbolo | 14 | "symbol" | Obsoleto. |
JavaScript con ámbito | 15 | "javascriptConÁmbito" | Obsoleto. |
entero de 32 bits | 16 | "int" | |
Marca de tiempo | 17 | "marca de tiempo" | |
entero de 64 bits | 18 | "long" | |
Decimal128 | 19 | "Decimal" | |
Min key | -1 | "minKey" | |
Clave máxima | 127 | "maxKey" |
El
$typeEl operador admite el uso de estos valores para consultar campos por su tipo BSON.$typetambién admite elnumberalias, que coincide con los tipos BSON entero, decimal, doble y largo.El
$typeoperador de agregación devuelve el tipo BSON de su argumento.El operador de agregación
$isNumberdevuelvetruesi su argumento es un entero BSON, decimal, double o long. Novedad en la versión 4.4
Para determinar el tipo de un campo, consultar Comprobación de tipo.
Para convertir BSON a JSON, consultar la referencia de Extended JSON.
Las siguientes secciones describen consideraciones especiales para BSON types.
Datos binarios
Un valor binario BSON binData es una matriz de bytes. Un valor binData tiene un subtipo que indica cómo interpretar los datos binarios. La siguiente tabla muestra los subtipos.
Número | subtipo |
|---|---|
0 | Subtipo binario genérico |
1 | Datos de funciones |
2 | Binario (antiguo) |
3 | UUID (antiguo) |
4 | UUID |
5 | MD5 |
6 | Valor BSON cifrado |
7 | Datos de series de tiempo comprimidos Nuevo en la versión 5.2. |
128 | Datos personalizados |
ObjectId
Los ObjectIds son pequeños, probablemente únicos, rápidos de generar y ordenados. Los valores de ObjectId tienen una longitud de 12 bytes y consisten en:
Una marca de tiempo de 4 bytes, que representa la creación del ObjectId, medida en segundos desde la Unix epoch.
Un valor aleatorio de 5bytes generado una vez por cada proceso del lado del cliente. Este valor aleatorio es único para la máquina y el proceso. Si el proceso se reinicia o el nodo primario del proceso cambia, este valor se vuelve a generar.
Un contador de 3bytes que se incrementa por cada proceso del lado del cliente, inicializado a un valor aleatorio. El contador se restablece cuando un proceso se reinicia.
Para los valores de marca de tiempo y contador, los bytes más significativos aparecen primero en la secuencia de bytes (big-endian). Esto es diferente de otros valores de BSON, donde los bytes menos significativos aparecen primero (little-endian).
Si se utiliza un valor entero para crear un ObjectId, el entero reemplaza la marca de tiempo.
En MongoDB, cada documento almacenado en una colección estándar requiere un campo _id único que actúa como llave primaria. Si un documento insertado omite el campo _id, el controlador de MongoDB genera automáticamente un ObjectId para el campo _id.
Esto también se aplica a los documentos insertados mediante operaciones de actualización con inserción: true.
Los clientes de MongoDB deben añadir un campo _id con un ObjectId único. El uso de ObjectIds para el campo _id ofrece los siguientes beneficios adicionales:
Puedes acceder al tiempo de creación de
ObjectIdenmongoshutilizando el métodoObjectId.getTimestamp().Los ObjectIds están ordenados de forma aproximada por el tiempo de creación, pero no están perfectamente ordenados. Ordenar una colección en un campo
_idque contiene valoresObjectIdes aproximadamente equivalente a ordenar por tiempo de creación.Importante
Aunque los valores de ObjectId deberían aumentar con el tiempo, no son necesariamente monotónicos. Esto es porque ellos:
Solo contienen un segundo de resolución temporal, por lo que los valores ObjectId creados dentro del mismo segundo no tienen un orden garantizado y
Son generados por los clientes, que pueden tener relojes del sistema diferentes.
Utilice los ObjectId() métodos para establecer y recuperar valores de ObjectId.
A partir de MongoDB 5.0, mongosh reemplaza el shell heredado mongo. Los métodos ObjectId() funcionan de manera diferente en mongosh que en el shell mongo heredado. Para más información sobre los métodos heredados, consultar el Shell mongo heredado.
String
Las cadenas BSON son UTF-8. En general, los controladores de cada lenguaje de programación convierten del formato de string del lenguaje a UTF-8 al serializar y deserializar BSON. Esto hace posible almacenar con facilidad la mayoría de los caracteres internacionales en cadenas BSON. [1] Además, los query $regex de MongoDB admiten UTF-8 en la cadena regex.
| [1] | Dadas las cadenas de caracteres que utilizan conjuntos de caracteres UTF-8, usar sort() en las cadenas será razonablemente correcto. Sin embargo, debido a que internamente sort() utiliza la API de C++ strcmp, el orden de clasificación puede gestionar algunos caracteres de manera incorrecta. |
Marcas de tiempo
BSON tiene un tipo especial de marca de tiempo para uso interno de MongoDB y no está asociado con el tipo Date normal. Este tipo de marca de tiempo interno es un valor de 64 bits donde:
los 32 bits más significativos son un valor
time_t(segundos desde la Unix epoch)los 32 bits menos significativos son un
ordinalque incrementa para operaciones dentro de un segundo dado.
Aunque el formato BSON es de tipo little-endian y, por lo tanto, almacena primero los bits menos significativos, la instancia de mongod siempre compara el valor time_t antes que el valor ordinal en todas las plataformas, independientemente de la endianness.
En la replicación, el oplog tiene un campo ts. Los valores de este campo reflejan el operation time, que utiliza un valor de marca de tiempo BSON.
Dentro de una sola instancia de mongod, los valores de marca de tiempo en el oplog siempre son únicos.
Nota
El tipo de marca de tiempo BSON es para uso interno de MongoDB. En la mayoría de los casos, en el desarrollo de aplicaciones, es ideal usar el tipo de fecha BSON. Consultar Fecha para obtener más información.
fecha
BSON Date es un entero de 64 bits que representa la cantidad de milisegundos desde la Unix epoch (1 de enero de 1970). Esto da como resultado un rango de fechas representable de aproximadamente 290 millones de años hacia el pasado y el futuro.
La especificación oficial de BSON se refiere al tipo de dato BSON como fecha y hora UTC.
El tipo de fecha BSON es con signo. [2] Los valores negativos representan fechas anteriores a 1970.
Para crear una Date en mongosh, puedes usar el constructor new Date() o ISODate().
Crea una fecha con el constructor New Date()
Para construir un Date con el constructor new Date(), ejecute el siguiente comando:
var mydate1 = new Date()
La variable mydate1 muestra una fecha y una hora envueltas en un ISODate:
mydate1
ISODate("2020-05-11T20:14:14.796Z")
Crea una fecha con el constructor ISODate()
Para crear una Date usando el constructor ISODate(), ejecuta el siguiente comando:
var mydate2 = ISODate()
La variable mydate2 almacena una fecha y hora envuelta como un ISODate:
mydate2
ISODate("2020-05-11T20:14:14.796Z")
Convierte una fecha a una string
Para imprimir el Date en un formato string, utilice el método toString():
mydate1.toString()
Mon May 11 2020 13:14:14 GMT-0700 (Pacific Daylight Time)
Devuelve la porción del mes de una fecha
También puedes devolver la parte del mes del valor Date. Los meses están indexados desde cero, por lo que enero es el mes 0.
mydate1.getMonth()
4
| [2] | Antes de la versión 2.0, los valores Date se interpretaron incorrectamente como enteros sin signo, lo que afectó las clasificaciones, los query de rango y los índices en los campos Date. Debido a que los índices no se recrean al actualizar, vuelva a indexar si creó un índice sobre los valores de Date con una versión anterior, y las fechas anteriores a 1970 son relevantes para su aplicación. |
decimal128 Tipo de dato BSON
decimal128 Es una 128representación decimal de bits para almacenar números muy grandes o muy precisos, siempre que sea importante redondear decimales. Se creó en agosto de 2009 como parte de la revisión IEEE 754-2008 de coma flotante. Si necesita alta precisión al trabajar con tipos de datos BSON, debe decimal128 usar.
decimal128 soporta 34 cifras decimales de precisión, o significand junto con un rango de exponente de -6143 a +6144. El significando no está normalizado en el estándar decimal128, lo que permite múltiples representaciones posibles: 10 x 10^-1 = 1 x 10^0 = .1 x 10^1 = .01 x 10^2, etc. Tener la capacidad de almacenar valores máximos y mínimos en el orden de 10^6144 y 10^-6143, respectivamente, permite mucha precisión.
Utilice decimal128 con el Decimal128() constructor
En MongoDB, puedes almacenar datos en formato decimal128 utilizando el constructor Decimal128(). Si pasas el valor decimal como una string, MongoDB almacena el valor en la base de datos de la siguiente manera:
Decimal128("9823.1297")
También puede pasar el valor decimal como un double:
Decimal128.fromStringWithRounding("1234.99999999999")
También se debe considerar el uso y el soporte que el lenguaje de programación tiene para decimal128. Los siguientes lenguajes no admiten esta funcionalidad de forma nativa y requieren un plugin o paquete adicional para obtener la funcionalidad:
Python: El módulo decimal.Decimal se puede utilizar para la aritmética de punto flotante.
Java: la clase Java BigDecimal ofrece soporte para números
decimal128.Node.js: Hay varios paquetes que proporcionan soporte, como js-big-decimal o Nodo.js bigdecimal disponibles en npm.
Casos de uso
Cuando realizas cálculos matemáticos mediante programación, a veces puedes recibir resultados inesperados. El siguiente ejemplo en Node.js arroja resultados incorrectos:
> 0.1 0.1 > 0.2 0.2 > 0.1 * 0.2 0.020000000000000004 > 0.1 + 0.1 0.010000000000000002
De manera similar, el siguiente ejemplo en Java produce un resultado incorrecto:
1 class Main { 2 public static void main(String[] args) { 3 System.out.println("0.1 * 0.2:"); 4 System.out.println(0.1 * 0.2); 5 } 6 }
1 0.1 * 0.2: 2 0.020000000000000004
Los mismos cálculos en Python, Ruby, Rust y otros lenguajes producen los mismos resultados. Esto ocurre porque los números de punto flotante binarios no representan bien los valores de base 10.
Por ejemplo, el 0.1 utilizado en los ejemplos anteriores se representa en binario como 0.0001100110011001101. La mayoría de las veces, esto no causa problemas significativos. Sin embargo, en aplicaciones como las de finanzas o banca, donde la precisión es importante, se debe usar decimal128 como el tipo de dato.
BSON con controladores MongoDB
Para ver cómo controladores específicos manejan BSON, consulte la documentación de su controlador: