Overview
En esta guía, puede aprender a utilizar el formato de datos JSON extendido cuando interactúe con documentos de MongoDB.
JSON es un formato de datos legible por humanos que representa los valores de objetos, arreglos, números, cadenas, booleanos y nulos. Este formato solo admite un subconjunto de tipos de datos BSON, que es el formato que utiliza MongoDB para almacenar datos. El formato Extended JSON admite más BSON types, definiendo un conjunto reservado de claves con el prefijo "$" para representar información del tipo de campo que corresponde directamente a cada tipo en BSON.
Para obtener más información sobre JSON, BSON y JSON extendido, consulta el recurso JSON y BSON y la entrada del manual JSON extendido de MongoDB Server.
Formatos JSON extendidos
MongoDB Extended JSON proporciona formatos de string para representar datos BSON. Cada formato cumple con la RFC JSON y satisface casos de uso específicos.
La siguiente tabla describe cada formato JSON extendido:
Nombre | Descripción |
|---|---|
Extendido o Canónico | Un formato de string que evita la pérdida de información de tipo BSON durante las conversiones de datos. |
Relajado | Un formato de string que describe documentos BSON con cierta pérdida de información de tipo. |
Shell | Un formato de string que coincide con la sintaxis utilizada en el shell de MongoDB. |
Nota
El driver de Scala analiza el tipo JSON extendido $uuid de una string a un objeto Binary de subtipo binario 4. Para obtener más información sobre el análisis del campo $uuid, consulta la sección de reglas especiales para analizar los campos $uuid en la especificación JSON extendida.
Ejemplos de JSON extendido
Los siguientes ejemplos muestran un documento que contiene un campo ObjectId, una fecha y un número largo representado en cada formato Extendido de JSON. Haz clic en la pestaña que corresponda al formato del ejemplo que desees ver:
{ "_id": { "$oid": "573a1391f29313caabcd9637" }, "createdAt": { "$date": { "$numberLong": "1601499609" }}, "numViews": { "$numberLong": "36520312" }}{ "_id": { "$oid": "573a1391f29313caabcd9637" }, "createdAt": { "$date": "2020-09-30T18:22:51.648Z" }, "numViews": 36520312}{ "_id": ObjectId("573a1391f29313caabcd9637"), "createdAt": ISODate("2020-09-30T18:22:51.648Z"), "numViews": NumberLong("36520312")}Leer JSON extendido
Puede leer un string JSON extendido en objetos Scala utilizando las clases de documentos del driver de Scala o utilizando la librería BSON directamente. Las siguientes secciones muestran cómo utilizar cada enfoque.
Clases de documentos
Puede leer una string JSON extendida en un objeto de documento Scala llamando al método estático parse() en BsonDocument y luego envolviendo el resultado en una instancia de Scala Document. Este enfoque analiza la string JSON extendida en cualquiera de los formatos y devuelve un Document que contiene los datos.
El siguiente ejemplo muestra cómo puedes leer una string JSON extendida en un objeto Document llamando a BsonDocument.parse() y pasando el resultado a la fábrica Document:
val ejsonStr = """{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "myNumber": {"$numberLong": "4794261"}}"""val document = Document(BsonDocument.parse(ejsonStr))println(document)Para obtener más información sobre los documentos en MongoDB, consulte documento en el manual de MongoDB Server.
Librería BSON
También puede leer un string JSON extendido en objetos Scala sin usar las clases de documentos del driver de Scala mediante la clase JsonReader . Esta clase contiene métodos para analizar secuencialmente los campos y valores en cualquier formato del string JSON extendido, y los devuelve como objetos Scala. Las clases de documentos del driver también utilizan esta clase para analizar JSON extendido.
El siguiente ejemplo de código muestra cómo puede utilizar la clase JsonReader para convertir una string de Extended JSON en objetos Scala:
val ejsonStr = """{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "myNumber": {"$numberLong": "4794261"}}"""val reader = new JsonReader(ejsonStr)reader.readStartDocument()val id = reader.readObjectId("_id")val myNumber = reader.readInt64("myNumber")reader.readEndDocument()println(s"$id is type: ${id.getClass.getName}")println(s"$myNumber is type: ${myNumber.getClass.getName}")Para más información, consulta la JsonReader Documentación de la API.
Advertencia
Validar la entrada no confiable antes de convertir JSON a BSON
Si convierte una string JSON a BSON y utiliza el BSON resultante en una query, una actualización o un comando, un atacante puede inyectar operadores o valores de campo inesperados que cambian el significado de la operación. Este riesgo es mayor cuando el JSON procede de un usuario, una solicitud de API o de otra fuente que no sea de confianza.
Para aprender más sobre la validación de la entrada antes de la conversión, consulte Validar la entrada no confiable antes de convertir JSON a BSON.
Guardar Extended JSON
Puede guardar una string JSON extendida de sus datos utilizando las clases de documentos del driver Scala o utilizando directamente la librería BSON. Las siguientes secciones muestran cómo utilizar cada enfoque.
Clases de documentos
Puedes guardar una string Extended JSON a partir de una instancia de Document o BsonDocument llamando al método toJson(). Por defecto, el método toJson() genera la string en el formato de modo relajado. Para utilizar un formato diferente, pasa una instancia de la clase JsonWriterSettings al método toJson().
El siguiente ejemplo llamar al método toJson() sin argumentos para generar el JSON extendido en el formato de modo relajado por defecto:
val document = Document( "_id" -> BsonObjectId(new ObjectId("507f1f77bcf86cd799439012")), "myNumber" -> BsonInt64(11223344L))val ejsonStr = document.toJson()println(ejsonStr)Librería BSON
También puede generar una string JSON extendida a partir de datos en objetos Scala utilizando la librería BSON con la clase JsonWriter. Para construir una instancia de JsonWriter, pase una subclase de un Java Writer para especificar cómo desea generar el JSON extendido. Opcionalmente, puede pasar una instancia de JsonWriterSettings para especificar opciones como el formato JSON extendido. Por defecto, el JsonWriter utiliza el formato de modo relajado. Las clases de documentos del driver Scala también utilizan esta clase para convertir BSON a JSON extendido.
El siguiente ejemplo de código muestra cómo puedes usar JsonWriter para crear una string JSON extendida y enviarla a System.out. El ejemplo especifica el formato pasando el método de desarrolladores outputMode() la constante JsonMode.EXTENDED:
val writer = new StringWriter()val jsonWriter = new JsonWriter(writer, JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build())jsonWriter.writeStartDocument()jsonWriter.writeObjectId("_id", new ObjectId("507f1f77bcf86cd799439012"))jsonWriter.writeInt64("myNumber", 11223344L)jsonWriter.writeEndDocument()println(writer.toString())Para obtener más información sobre los métodos y clases mencionados en esta sección, consulta la siguiente documentación de la API:
Conversión personalizada de tipos BSON
Además de especificar el outputMode() para formatear la salida JSON, puede personalizar aún más la salida agregando convertidores a su instancia de JsonWriterSettings.Builder. Estos métodos convertidores detectan BSON types específicos y ejecutan la lógica definida por el Converter que se les pasa.
El siguiente código de muestra muestra cómo añadir convertidores, definidos como expresiones Lambda, para simplificar la salida JSON en el modo relajado:
val settings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .objectIdConverter((value, writer) => writer.writeString(value.toHexString)) .timestampConverter((value, writer) => { val instant = Instant.ofEpochSecond(value.getTime.toLong) writer.writeString( DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneOffset.UTC).format(instant)) }) .build()
val document = Document( "_id" -> BsonObjectId(new ObjectId("507f1f77bcf86cd799439012")), "createdAt" -> new BsonTimestamp(1601516589, 1), "myNumber" -> BsonInt64(4794261L))println(document.toJson(settings))Para obtener más información sobre los métodos y clases mencionados en esta sección, consulta la siguiente documentación de la API: