对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用扩展JSON数据

在本指南中,您可以学习;了解在与MongoDB文档交互时如何使用扩展JSON数据格式。

JSON是一种人类可读的数据格式,用于表示对象值、数组、数字、字符串、布尔值和空值。此格式仅支持BSON数据类型的子集,而MongoDB正是使用该格式来存储数据。扩展JSON格式支持更多BSON 类型,定义了一设立以 "$" 为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息。

要学习;了解有关JSON、 BSON和扩展JSON的更多信息,请参阅JSON和BSON资源以及扩展JSON MongoDB Server手册条目。

MongoDB扩展JSON提供字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定的使用案例。

下表描述了每种扩展JSON格式:

名称
说明

扩展规范

一种 string 格式,可避免在数据转换过程中丢失 BSON 类型信息。
这种格式优先考虑类型保存,但会牺牲人类可读性以及与旧格式的互操作性。JsonMode.EXTENDED

宽松

一种 string 格式,用于描述 BSON 文档,但会丢失某些类型信息。
这种格式优先考虑人类可读性和互操作性,但会丢失某些类型信息。JsonMode.RELAXED

Shell

与 MongoDB shell 中使用的语法匹配的 string 格式。
该格式优先考虑与 MongoDB shell 的兼容性,后者通常使用 JavaScript 函数来表示类型。JsonMode.SHELL

解析 $uuid 字段的特殊规则

以下示例显示了包含对象标识符、日期和长数字字段的文档,这些字段分别以扩展 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值读入Java对象:

要将扩展JSON字符串读入Java文档对象,请从 DocumentBsonDocument 类中调用 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}}

要在不使用文档类的情况下将扩展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

本部分介绍如何通过以下方式从Java对象写入扩展JSON值:

要从 DocumentBsonDocument对象写入扩展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}

要从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"}}

除了指定扩展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 文档: