Overview
在本指南中,您可以学习;了解在与MongoDB文档交互时如何使用扩展JSON数据格式。
JSON是一种人类可读的数据格式,用于表示对象值、数组、数字、字符串、布尔值和空值。此格式仅支持BSON数据类型的子集,而MongoDB正是使用该格式来存储数据。扩展JSON格式支持更多BSON 类型,定义了一设立以 "$" 为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息。
要学习;了解有关JSON、 BSON和扩展JSON的更多信息,请参阅JSON和BSON资源以及扩展JSON MongoDB Server手册条目。
扩展 JSON 格式
MongoDB扩展JSON提供字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定的使用案例。
下表描述了每种扩展JSON格式:
名称 | 说明 |
|---|---|
扩展或规范 | 一种 string 格式,可避免在数据转换过程中丢失 BSON 类型信息。 |
宽松 | 一种 string 格式,用于描述 BSON 文档,但会丢失某些类型信息。 |
Shell | 与 MongoDB shell 中使用的语法匹配的 string 格式。 |
扩展 JSON 示例
以下示例显示了包含对象标识符、日期和长数字字段的文档,这些字段分别以扩展 JSON 格式表示。单击与要查看的示例格式相对应的选项卡:
{ "_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") }
读取扩展 JSON
本节介绍如何通过以下方式将扩展JSON值读入Java对象:
使用文档类
要将扩展JSON字符串读入Java文档对象,请从 Document 或 BsonDocument 类中调用 parse() 静态方法。此方法解析扩展JSON字符串并将其数据存储在指定文档类的实例中。
以下示例使用 parse() 方法将扩展JSON字符串读入 Document对象:
String ejsonStr = "{ \"_id\": { \"$oid\": \"507f1f77bcf86cd799439011\" }," + " \"myNumber\": { \"$numberLong\": \"4794261\" } }"; Document doc = Document.parse(ejsonStr); System.out.println(doc);
Document{{_id=507f1f77bcf86cd799439011, myNumber=4794261}}
使用 JsonReader 类
要在不使用文档类的情况下将扩展JSON字符串读入Java对象,请使用BSON库的 JsonReader 类。此类包含用于按顺序解析扩展JSON字符串的字段和值并将它们作为Java对象返回的方法。驱动程序的文档类也使用此类来解析 扩展JSON。
以下代码使用 JsonReader 类提供的方法将扩展JSON字符串转换为Java对象:
String string = "{ \"_id\": { \"$oid\": \"507f1f77bcf86cd799439011\" }," + " \"myNumber\": { \"$numberLong\": \"4794261\" } }"; JsonReader jsonReader = new JsonReader(string); jsonReader.readStartDocument(); // Reads the "_id" field value jsonReader.readName("_id"); ObjectId id = jsonReader.readObjectId(); // Reads the "myNumber" field value jsonReader.readName("myNumber"); long myNumber = jsonReader.readInt64(); jsonReader.readEndDocument(); System.out.println(id + " is type: " + id.getClass().getName()); System.out.println(myNumber + " is type: " + Long.class.getName()); jsonReader.close();
507f1f77bcf86cd799439011 is type: org.bson.types.ObjectId 4794261 is type: java.lang.Long
写入扩展 JSON
本部分介绍如何通过以下方式从Java对象写入扩展JSON值:
使用文档类
要从 Document 或 BsonDocument对象写入扩展JSON字符串,请调用 toJson() 方法。 您可以向此方法传递一个 JsonWriterSettings对象参数,以指定扩展JSON格式。
以下示例将 Document 数据写入为宽松模式扩展JSON:
Document doc = new Document() .append("_id", new ObjectId("507f1f77bcf86cd799439012")) .append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) .append("myNumber", 4794261); JsonWriterSettings settings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .build(); System.out.println(doc.toJson(settings));
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "createdAt": {"$date": "2020-09-30T21:00:09Z"}, "myNumber": 4794261}
使用 JsonWriter 类
要从Java对象中存储的数据输出扩展JSON字符串,可以使用BSON库的 JsonWriter 类。要构造 JsonWriter对象,请传递Java Writer 的子类以指定希望如何输出扩展JSON。 (可选)您可以传递 JsonWriterSettings实例来指定选项,例如扩展JSON格式。默认下,JsonWriter 使用宽松模式格式。 BSON文档类也使用此类将BSON转换为扩展JSON。
以下示例使用 JsonWriter对象创建规范模式扩展JSON字符串值并将其输出到 System.out:
JsonWriterSettings settings = JsonWriterSettings.builder() .outputMode(JsonMode.EXTENDED) .build(); JsonWriter jsonWriter = new JsonWriter( new BufferedWriter(new OutputStreamWriter(System.out)), settings); jsonWriter.writeStartDocument(); jsonWriter.writeName("_id"); jsonWriter.writeObjectId(new ObjectId("507f1f77bcf86cd799439012")); jsonWriter.writeName("myNumber"); jsonWriter.writeInt64(11223344L); jsonWriter.writeEndDocument(); jsonWriter.flush();
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}}
自定义 BSON 类型转换
除了指定扩展JSON输出格式之外,您还可以通过向 JsonWriterSettings对象添加转换器来进一步自定义输出。这些转换器方法指定在转换进程中处理不同数据类型的逻辑。
以下示例转换与使用文档类示例相同的文档。但是,此示例在 JsonWriterSettings对象中定义了 objectIdConverter() 和 dateTimeConverter() 转换器方法,以简化宽松模式扩展JSON输出:
JsonWriterSettings settings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .objectIdConverter((value, writer) -> writer.writeString(value.toHexString())) .dateTimeConverter((value, writer) -> { ZonedDateTime zonedDateTime = Instant.ofEpochMilli(value).atZone(ZoneOffset.UTC); writer.writeString(DateTimeFormatter.ISO_DATE_TIME.format(zonedDateTime)); }) .build(); Document doc = new Document() .append("_id", new ObjectId("507f1f77bcf86cd799439012")) .append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) .append("myNumber", 4794261); System.out.println(doc.toJson(settings));
{"_id": "507f1f77bcf86cd799439012", "createdAt": "2020-09-30T21:00:09Z", "myNumber": 4794261}
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: