Overview
このガイドでは、 MongoDBドキュメントを操作するときに拡張JSONデータ形式を使用する方法を学習できます。
JSON は、オブジェクト、配列、数値、string、ブール値、null の値を表す人間が判読可能なデータ形式です。この形式は、 MongoDB がデータを保存するために使用する形式であるBSONデータ型のサブセットのみをサポートします。拡張JSON形式はより多くのBSONタイプをサポートしており、 BSONの各タイプに直接対応するフィールドタイプ情報を表すために "$" のプレフィックスが付いたキーの予約セットを定義します。
JSON、 BSON、 拡張JSONの詳細については、JSONとBSONリソースおよび拡張JSON MongoDB Server のマニュアル エントリを参照してください。
拡張 JSON 形式
MongoDB拡張JSON は、 BSONデータを表す string 形式を提供します。各形式はJSON RFCに準拠し、特定のユースケースを満たしています。
次の表は、各 拡張JSON形式について説明したものです。
名前 | 説明 |
|---|---|
拡張または標準 | データ変換中にBSON type 情報が喪失しないようにする |
緩和 | A string format that describes BSON documents with some type information loss. |
Shell | MongoDB シェルで使用される構文に一致する string形式。この形式は、型を表すためにJavaScript関数を多く使用するMongoDB |
注意
Scalaドライバーは、$uuid 拡張JSONタイプを string からバイナリ サブタイプ のBinary 4オブジェクトに解析します。$uuid フィールド解析の詳細については、拡張JSON仕様の $uuid フィールドを解析するための特別なルール セクションを参照してください。
拡張 JSON の例
次の例は、それぞれの拡張 JSON 形式で表される ObjectId、date、long 数値フィールドを含むドキュメントを示しています。 表示する例の形式に対応するタブをクリックします。
{ "_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 の読み取り
Scala ドライバーのドキュメント クラスを使用するか、BSON ライブラリを直接使用することで、Extended JSON string を Scala オブジェクトに読み込むことができます。次のセクションでは、各アプローチの使用方法を示します。
ドキュメント クラス
BsonDocument で parse() 静的メソッドを呼び出し、その結果を Scala Document インスタンスでラップすることで、拡張 JSON string を Scala ドキュメント オブジェクトに読み込むことができます。このアプローチでは、拡張 JSON string をいずれかの形式でパースし、データを含む Document を返します。
次の例は、BsonDocument.parse()を呼び出し、その結果をDocumentファクトリに渡すことで、拡張 JSON string をDocumentオブジェクトに読み込む方法を示しています。
val ejsonStr = """{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "myNumber": {"$numberLong": "4794261"}}""" val document = Document(BsonDocument.parse(ejsonStr)) println(document)
To learn more about documents in MongoDB, see Documents in the MongoDB Server manual.
BSON ライブラリ
JsonReader クラスを使用すると、Scala ドライバーのドキュメント クラスを使用せずに Extended JSON string を Scala オブジェクトに読み込むこともできます。このクラスには、Extended JSON string のあらゆる形式でフィールドと値を順序にパースし、それらを Scala オブジェクトとして返すメソッドが含まれています。ドライバーのドキュメント クラスでも、Extended JSON をパースするためにこのクラスを使用します。
次のコード例は、JsonReader クラスを使用して拡張 JSON string を 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}")
詳細については、JsonReader APIドキュメント を参照してください。
警告
JSON をBSONに変換する前に信頼できない入力を検証する
JSON string をBSONに変換し、クエリ、アップデート、またはコマンドで結果のBSONを使用すると、攻撃者は操作の意味を変更する演算子や予期しないフィールド値を挿入することができます。このリスクは、 JSONがユーザー、 APIリクエスト、または別の信頼できないソースからのものである場合に最も高くなります。
To learn more about validating input before conversion, see Validate Untrusted Input Before Converting JSON to BSON.
拡張 JSON の書込み (write)
Scala ドライバーのドキュメントクラスを使用するか、BSON ライブラリを直接使用することで、データから拡張 JSON string を書き込むことができます。次のセクションでは、各アプローチの使用方法を示します。
ドキュメント クラス
toJson()メソッドを呼び出すことで、DocumentまたはBsonDocumentのインスタンスから拡張 JSON string を書き込めます。デフォルトでは、toJson()メソッドは緩和モード形式で string を出力します。別の形式を使用するには、JsonWriterSettingsクラスのインスタンスをtoJson()メソッドに渡します。
次の例では、toJson() メソッドを引数なしで呼び出し、拡張 JSON をデフォルトの緩和モード形式で出力します。
val document = Document( "_id" -> BsonObjectId(new ObjectId("507f1f77bcf86cd799439012")), "myNumber" -> BsonInt64(11223344L) ) val ejsonStr = document.toJson() println(ejsonStr)
BSON ライブラリ
BSON ライブラリと JsonWriter クラスを使用して、Scala オブジェクトのデータから Extended JSON string を出力することもできます。JsonWriter のインスタンスを構築するには、Java Writer のサブクラスを渡して Extended JSON の出力方法を指定します。オプションで、JsonWriterSettings インスタンスを渡して Extended JSON 形式などのオプションを指定することができます。デフォルトでは、JsonWriter は緩和モード形式を使用します。Scala ドライバーのドキュメント クラスも、BSON を Extended JSON に変換するためにこのクラスを使用します。
次のコード例は、JsonWriter を使用して拡張JSON string を作成し、System.out に出力する方法を示しています。例では、outputMode() ビルダ メソッドに 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())
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
カスタム BSON 型変換
JSON 出力の形式を設定するために outputMode() を指定するだけでなく、JsonWriterSettings.Builder インスタンスに変換メソッドを追加することで出力をさらにカスタマイズできます。これらの変換メソッドは特定の BSON types を検出し、それらに渡された Converter によって定義されたロジックを実行します。
次のサンプル コードは、Lambda 式として定義される変換器を追加して緩和モードの JSON 出力を簡素化する方法を示しています。
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))
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。