对于 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格式:

名称
说明

扩展或规范

一种字符串格式,可避免数据转换期间丢失BSON类型信息。这种格式优先考虑类型保留,但会牺牲人类可读性以及与旧格式的互操作性。要学习;了解有关此格式的更多信息,请参阅API文档中的
JsonMode.EXTENDED。

宽松

一种字符串格式,用于描述丢失某些类型信息的BSON文档。这种格式优先考虑人类可读性和互操作性,但会丢失某些类型的信息。
Java Reactive Streams驾驶员默认使用宽松模式。要学习;了解有关此格式的更多信息,请参阅API文档中的 JsonMode.RELAXED。

Shell

与MongoDB
Shell中使用的语法相匹配的字符串格式。这种格式优先考虑与MongoDB Shell 的兼容性,MongoDB Shell 通常使用JavaScript函数来表示类型。要学习;了解有关此格式的更多信息,请参阅API文档中的 JsonMode.SHELL。

注意

Java Reactive Streams驾驶员将$uuid 扩展JSON类型从字符串解析为二进制子类型 的BsonBinary 4对象。有关$uuid 字段解析的更多信息,请参阅扩展JSON规范中解析 $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 对象中:

要将 Extended JSON string 读取到 Java 文档对象中,调用 Document 或 BsonDocument 类中的 parse() 静态方法。此方法解析 Extended JSON string,并将其数据存储在指定文档类的实例中。

以下示例使用 parse() 方法将扩展JSON字符串读入 Document对象:

String ejsonStr = "{ \"_id\": { \"$oid\": \"507f1f77bcf86cd799439011\" },"
+ " \"myNumber\": { \"$numberLong\": \"4794261\" } }";
Document doc = Document.parse(ejsonStr);
System.out.println(doc);

要将扩展 JSON string 读入 Java 对象而不使用文档类,请使用 BSON 库的 JsonReader 类。该类包含用于按顺序解析扩展 JSON string 的字段和值并将其作为 Java 对象返回的方法。驱动程序的文档类也使用该类来解析扩展 JSON。

以下代码使用 JsonReader 类提供的方法将扩展JSON string 转换为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();

警告

在将JSON转换为BSON之前验证不可信输入

如果将JSON字符串转换为BSON并在查询、 更新或 command 中使用生成的BSON ,则攻击者可以注入操作符或意外的字段值,从而更改操作的含义。当JSON源自用户、 API请求或其他不可信来源时,这种风险最大。

要学习;了解有关在转换前验证输入的更多信息,请参阅在将JSON转换为BSON之前验证不受信任的输入。

本节介绍如何以以下方式从 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));

要从 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();

除了指定扩展JSON输出格式之外,您还可以通过向 JsonWriterSettings对象添加转换器来进一步自定义输出。这些转换器方法指定在转换进程中处理不同数据类型的逻辑。

以下示例转换与使用文档类示例相同的文档。但是,此示例在 对象中定义了objectIdConverter() dateTimeConverter()和JsonWriterSettings 转换器方法,以简化宽松模式扩展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));

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: