JSON スキーマ
バージョン 3.6 の時点で、MongoDB は、提供された JSON スキーマ (英語) に対してドキュメントを検証するコレクションをサポートしています。次の例に示すように、コレクションの作成時にスキーマ自体、検証アクションとレベルの両方を定義できます。
{
"type": "object", (1)
"required": [ "firstname", "lastname" ], (2)
"properties": { (3)
"firstname": { (4)
"type": "string",
"enum": [ "luke", "han" ]
},
"address": { (5)
"type": "object",
"properties": {
"postCode": { "type": "string", "minLength": 4, "maxLength": 5 }
}
}
}
}
1 | JSON スキーマドキュメントは常にルートからドキュメント全体を記述します。スキーマは、プロパティとサブドキュメントを記述する埋め込みスキーマオブジェクトを含めることができるスキーマオブジェクト自体です。 |
2 | required は、ドキュメント内でどのプロパティが必要であるかを説明するプロパティです。他のスキーマ制約とともにオプションで指定できます。使用可能なキーワード (英語) については、MongoDB のドキュメントを参照してください。 |
3 | properties は、object 型を記述するスキーマオブジェクトに関連しています。これには、プロパティ固有のスキーマ制約が含まれます。 |
4 | firstname は、ドキュメント内の firstname フィールドの制約を指定します。ここでは、可能なフィールド値を宣言する文字列ベースの properties 要素です。 |
5 | address は、postCode フィールドの値のスキーマを定義するサブドキュメントです。 |
スキーマを提供するには、スキーマドキュメントを指定するか (つまり、Document
API を使用してドキュメントオブジェクトを解析または構築する)、または org.springframework.data.mongodb.core.schema
の Spring Data の JSON スキーマユーティリティを使用してスキーマドキュメントを構築します。MongoJsonSchema
は、すべての JSON スキーマ関連の操作のエントリポイントです。次の例は、MongoJsonSchema.builder()
を使用して JSON スキーマを作成する方法を示しています。
MongoJsonSchema.builder() (1)
.required("lastname") (2)
.properties(
required(string("firstname").possibleValues("luke", "han")), (3)
object("address")
.properties(string("postCode").minLength(4).maxLength(5)))
.build(); (4)
1 | スキーマビルダーを取得して、流れるような API を使用してスキーマを構成します。 |
2 | ここに示すように必要なプロパティを直接構成するか、3 のように詳細を指定して構成します。 |
3 | 必須の文字列型の firstname フィールドを構成し、luke 値と han 値のみを許可します。プロパティは型指定することも、型指定しないこともできます。JsonSchemaProperty の静的インポートを使用して、構文をもう少しコンパクトにし、string(…) などのエントリポイントを取得します。 |
4 | スキーマオブジェクトを構築します。 |
ゲートウェイインターフェース上の静的メソッドを通じて使用できる、事前定義された厳密に型指定されたスキーマオブジェクト (JsonSchemaObject
および JsonSchemaProperty
) がすでにいくつかあります。ただし、次の例に示すように、カスタムプロパティ検証ルールを構築する必要がある場合があります。これはビルダー API を通じて作成できます。
// "birthdate" : { "bsonType": "date" }
JsonSchemaProperty.named("birthdate").ofType(Type.dateType());
// "birthdate" : { "bsonType": "date", "description", "Must be a date" }
JsonSchemaProperty.named("birthdate").with(JsonSchemaObject.of(Type.dateType()).description("Must be a date"));
次の例に示すように、CollectionOptions
は、コレクションのスキーマサポートへのエントリポイントを提供します。
$jsonSchema
でコレクションを作成する MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
スキーマの生成
スキーマの設定は時間のかかる作業となる可能性があるため、設定を決定するすべての人には、十分な時間をかけて行うことをお勧めします。これは重要ですが、スキーマの変更は難しい場合があります。ただし、それを躊躇したくない場合もあるかもしれません。そこで JsonSchemaCreator
が役に立ちます。
JsonSchemaCreator
とそのデフォルト実装は、マッピングインフラストラクチャによって提供されるドメイン型のメタデータから MongoJsonSchema
を生成します。これは、アノテーション付きプロパティと潜在的なカスタム変換が考慮されることを意味します。
public class Person {
private final String firstname; (1)
private final int age; (2)
private Species species; (3)
private Address address; (4)
private @Field(fieldType=SCRIPT) String theForce; (5)
private @Transient Boolean useTheForce; (6)
public Person(String firstname, int age) { (1) (2)
this.firstname = firstname;
this.age = age;
}
// gettter / setter omitted
}
MongoJsonSchema schema = MongoJsonSchemaCreator.create(mongoOperations.getConverter())
.createSchemaFor(Person.class);
template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
{
'type' : 'object',
'required' : ['age'], (2)
'properties' : {
'firstname' : { 'type' : 'string' }, (1)
'age' : { 'bsonType' : 'int' } (2)
'species' : { (3)
'type' : 'string',
'enum' : ['HUMAN', 'WOOKIE', 'UNKNOWN']
}
'address' : { (4)
'type' : 'object'
'properties' : {
'postCode' : { 'type': 'string' }
}
},
'theForce' : { 'type' : 'javascript'} (5)
}
}
1 | 単純なオブジェクトのプロパティは通常のプロパティとみなされます。 |
2 | プリミティブ型は必須プロパティとみなされます |
3 | 列挙型は可能な値に制限されます。 |
4 | オブジェクト型のプロパティはインスペクションされ、ネストされたドキュメントとして表されます。 |
5 | コンバーターによって Code に変換される String 型のプロパティ。 |
6 | @Transient プロパティは、スキーマの生成時に省略されます。 |
String のような ObjectId に変換できる型を使用する _id プロパティは、@MongoId アノテーションを介して利用可能なより具体的な情報がない限り、{ type : 'object' } にマップされます。 |
Java | スキーマの種類 | ノート |
---|---|---|
|
| メタデータが利用可能な場合は |
|
| - |
|
| - |
|
| 可能な列挙値を保持する |
|
|
|
|
| - |
上記の例では、非常に正確に型指定されたソースからスキーマを導出する方法を示しました。ドメインモデル内で多態性要素を使用すると、Object
および汎用 <T>
型のスキーマ表現が不正確になる可能性があり、さらなる仕様がなければ { type : 'object' }
として表現される可能性があります。MongoJsonSchemaCreator.property(…)
を使用すると、スキーマをレンダリングするときに考慮する必要があるネストされたドキュメント型などの追加の詳細を定義できます。
class Root {
Object value;
}
class A {
String aValue;
}
class B {
String bValue;
}
MongoJsonSchemaCreator.create()
.property("value").withTypes(A.class, B.class) (1)
{
'type' : 'object',
'properties' : {
'value' : {
'type' : 'object',
'properties' : { (1)
'aValue' : { 'type' : 'string' },
'bValue' : { 'type' : 'string' }
}
}
}
}
1 | 指定された型のプロパティは 1 つの要素にマージされます。 |
MongoDB のスキーマフリーのアプローチにより、異なる構造のドキュメントを 1 つのコレクションに保存できます。これらは、共通の基本クラスを持ってモデル化できます。選択したアプローチに関係なく、MongoJsonSchemaCreator.merge(…)
は複数のスキーマを 1 つにマージする必要性を回避できます。
abstract class Root {
String rootValue;
}
class A extends Root {
String aValue;
}
class B extends Root {
String bValue;
}
MongoJsonSchemaCreator.mergedSchemaFor(A.class, B.class) (1)
{
'type' : 'object',
'properties' : { (1)
'rootValue' : { 'type' : 'string' },
'aValue' : { 'type' : 'string' },
'bValue' : { 'type' : 'string' }
}
}
}
1 | 指定された型のプロパティ (およびその継承されたプロパティ) は 1 つのスキーマに結合されます。 |
同じ名前のプロパティを結合するには、同じ JSON スキーマを参照する必要があります。次の例は、データ型の不一致のために自動的にマージできない定義を示しています。この場合、
|
暗号化されたフィールド
MongoDB 4.2 フィールドレベルの暗号化 (英語) では、個々のプロパティを直接暗号化できます。
以下の例に示すように、JSON スキーマを設定するときに、プロパティを暗号化されたプロパティ内にラップできます。
MongoJsonSchema schema = MongoJsonSchema.builder()
.properties(
encrypted(string("ssn"))
.algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
.keyId("*key0_id")
).build();
暗号化フィールドを手動で定義する代わりに、以下のスニペットに示すように @Encrypted
アノテーションを利用することができます。
@Document
@Encrypted(keyId = "xKVup8B1Q+CkHaVRx+qa+g==", algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Random") (1)
static class Patient {
@Id String id;
String name;
@Encrypted (2)
String bloodType;
@Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic") (3)
Integer ssn;
}
1 | encryptMetadata に設定されるデフォルトの暗号化設定。 |
2 | デフォルトの暗号化設定を使用して暗号化されたフィールド。 |
3 | デフォルトの暗号化アルゴリズムをオーバーライドする暗号化フィールド。 |
|
JSON スキーマの種類
次の表は、サポートされている JSON スキーマ型を示しています。
スキーマの種類 | Java 型 | スキーマのプロパティ |
---|---|---|
| - |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| (なし) |
|
| (なし) |
|
| (なし) |
|
| (なし) |
|
| (なし) |
|
| (なし) |
|
| (なし) |
untyped は、すべての型付きスキーマ型によって継承されるジェネリクス型です。すべての untyped スキーマプロパティを型付きスキーマ型に提供します。 |
詳しくは、$jsonSchema (英語) を参照してください。