MongoDBにはスキーマがないことは誰もが知っていますが、なぜスキーマ検証を実行する必要があるのでしょうか。 MongoDBのスキーマレス動作を使用してアプリケーションを開発し、概念実証として使用するのは簡単で迅速です。ただし、アプリケーションが本番環境に移行して安定して成熟した後は、スキーマを頻繁に変更する必要はなく、またお勧めできません。現時点では、アプリケーションを破壊する可能性のある不要なデータが挿入されないように、データベースにスキーマ検証を実施することが非常に重要です。これは、データが同じデータベース内の複数のソースから挿入されている場合に、はるかに重要になります。
スキーマ検証を使用すると、各コレクション内のドキュメントの特定の構造を定義できます。定義されたスキーマと一致しないドキュメントを挿入しようとすると、MongoDBはこの種の操作を拒否したり、検証アクションのタイプに応じて警告を発したりする可能性があります。
MongoDBは、スキーマを検証する2つの方法、ドキュメント検証とJSONスキーマ検証を提供します。 JSONスキーマ検証はドキュメント検証の拡張バージョンであるため、ドキュメント検証から始めましょう。
ドキュメントの検証
リレーショナルデータベースを使用したことのある開発者のほとんどは、データモデルまたはスキーマの予測可能性の重要性を知っています。そのため、MongoDBではバージョン3.2からドキュメント検証が導入されました。 MongoDBコレクションに検証ルールを追加する方法を見てみましょう。
次の種類のドキュメントを持つユーザーのコレクションがあるとします。
{
"name": "Alex",
"email": "[email protected]",
"mobile": "123-456-7890"
}
また、ユーザーコレクションに新しいドキュメントを追加するときに確認する検証は次のとおりです。
- 名前、メールフィールドは必須です
- 携帯電話番号は特定の構造に従う必要があります:xxx-xxx-xxxx
この検証を追加するには、新しいコレクションを作成するときに「validator」構造を使用できます。 Mongoシェルで次のクエリを実行します
db.createCollection("users", {
validator: {
$and: [
{
"name": {$type: "string", $exists: true}
},
{
"mobile": {$type: "string", $regex: /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/}
},
{
"email": {$type: "string", $exists: true}
}
]
}
})
次の出力が表示されます。
{ "ok" : 1 }
これで、検証ルールに従わずに新しいドキュメントを追加しようとすると、mongoは検証エラーをスローします。次の挿入クエリを実行してみてください。
クエリ:1
db.users.insert({
"name": "akash"
})
出力:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
クエリ:2
db.users.insert({
"name": "akash",
"email": "[email protected]",
"mobile": "123-456-7890"
})
出力:
WriteResult({ "nInserted" : 1 })
ただし、ドキュメント検証アプローチにはいくつかの制限があります。たとえば、ドキュメントに新しいキーと値のペアをいくつでも追加して、コレクションに挿入することができます。これは、ドキュメントの検証では防ぐことができません。次の例を考えてみましょう。
db.users.insert({
"name": "akash",
"email": "[email protected]",
"mobile": "123-456-7890",
"gender": "Male"
})
出力:
WriteResult({ "nInserted" : 1 })
これとは別に、ドキュメントの検証では値のみがチェックされます。 「name」ではなく「nmae」(typo)をキーとしてドキュメントを追加しようとすると、mongoはそれを新しいフィールドと見なし、ドキュメントがDBに挿入されるとします。本番データベースで作業しているときは、これらのことは避ける必要があります。これらすべてをサポートするために、MongoDBはバージョン3.6から「validator」コンストラクトを備えた「jsonSchema」演算子を導入しました。上記と同じ検証ルールを追加し、新しいフィールドやスペルミスのあるフィールドを追加しないようにする方法を見てみましょう。
SomeninesがMongoDBDBAになる-MongoDBを本番環境に導入MongoDBDownloadを無料でデプロイ、監視、管理、スケーリングするために知っておくべきことを学びましょうjsonSchema検証
mongoシェルで次のコマンドを実行し、「jsonSchema」演算子を使用して検証ルールを追加します。
db.runCommand(
{
"collMod": "users_temp",
"validator": {
"$jsonSchema": {
"bsonType": "object",
"additionalProperties": false,
"required": [
"name",
"email"
],
"properties": {
"_id": {},
"name": {
"bsonType": "string"
},
"email": {
"bsonType": "string"
},
"mobile": {
"bsonType": "string",
"pattern": "^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
}
}
}
}
})
次のドキュメントを挿入しようとするとどうなるか見てみましょう。
db.users.insert({
"name": "akash",
"email": "[email protected]",
"mobile": "123-456-7890",
"gender": "Male"
})
「jsonSchema」で性別フィールドを定義していないため、エラーがスローされます。
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
同様に、フィールド名にタイプミスがある場合、mongoは同じエラーをスローします。
上で定義したスキーマは、ドキュメントの検証で使用したものと同じです。さらに、フィールド名のタイプミスやドキュメントへの新しいフィールドの追加を回避するために、「additionalProperties」フィールドを追加しました。 「プロパティ」フィールドで定義されたフィールドのみが許可されます。 「jsonSchema」演算子で使用できるいくつかのプロパティの概要は次のとおりです。
- bsonType:配列|オブジェクト|文字列|ブール値|番号| null
- 必須:すべての必須フィールドの配列
- 列挙型:任意のフィールドで可能な値のみの配列
- 最小:フィールドの最小値
- maximum:フィールドの最大値
- minLength:フィールドの最小の長さ
- mixLength:フィールドの最大長
- プロパティ:有効なJSONスキーマのコレクション
- additionalProperties:プロパティフィールドで説明されている以外のフィールドを追加できないようにします
- title:任意のフィールドのタイトル。
- 説明:任意のフィールドの簡単な説明。
スキーマの検証とは別に、「jsonSchema」演算子は、集計パイプライン内の検索と照合の段階でも使用できます。
結論
ドキュメント/スキーマの検証は、すべての状況で必須または望ましいわけではありませんが、データベースを扱う開発者の生産性が向上するため、通常、データベースに追加することをお勧めします。ランダムなデータがないため、データベースからどのような応答が期待できるかがわかります。
この記事では、MongoDBでのスキーマ検証の重要性と、ドキュメント検証と「jsonSchema」演算子を使用してドキュメントレベルで検証を追加する方法について学習しました。