バージョン 3.2 で追加。
MongoDB は、アップデートおよび挿入中にスキーマ検証を実行する機能を提供します。
MongoDB Atlas でホストされる配置向け に UI でのスキーマ検証を実装 できます。
検証ルールを指定する
検証ルールはコレクションごとにあります。
新しいコレクションの作成時に検証ルールを指定するには、 db.createCollection()をvalidatorオプションとともに使用します。
既存のコレクションにドキュメント検証を追加するには、 validatorオプションを指定したcollModコマンドを使用します。
MongoDB は、次の関連オプションも提供します。
validationLevelオプションは、アップデート中に MongoDB が既存のドキュメントに検証ルールをどの程度厳密に適用するかを決定します。validationActionオプションは、MongoDB が検証ルールに違反するドキュメントをerrorして拒否するか、ログ内の違反についてはwarnして無効なドキュメントを許可するかどうかを決定します。
JSON Schema
バージョン 3.6 の新機能。
バージョン3.6以降、 MongoDB は JSON schema 検証 をサポートしています。 JSON schema検証を指定するには、validator 式で$jsonSchema演算子を使用します。
注意
JSON schema は、スキーマ検証を実行するための推奨手段です。
たとえば、次の例では、 JSON schemaを使用して検証ルールを指定しています。
db.createCollection("students", { validator: { $jsonSchema: { bsonType: "object", required: [ "name", "year", "major", "address" ], properties: { name: { bsonType: "string", description: "must be a string and is required" }, year: { bsonType: "int", minimum: 2017, maximum: 3017, description: "must be an integer in [ 2017, 3017 ] and is required" }, major: { enum: [ "Math", "English", "Computer Science", "History", null ], description: "can only be one of the enum values and is required" }, gpa: { bsonType: [ "double" ], description: "must be a double if the field exists" }, address: { bsonType: "object", required: [ "city" ], properties: { street: { bsonType: "string", description: "must be a string if the field exists" }, city: { bsonType: "string", description: "must be a string and is required" } } } } } } })
詳細については、$jsonSchema を参照してください。
bsonType の定義は、[ BSON types ]ページで確認できます。
その他のクエリ式
$jsonSchemaクエリ演算子を使用する JSON schema 検証に加えて、MongoDB は他の クエリ演算子による検証をサポートしています。ただし、次の例外があります。
たとえば、次の例では、 クエリ式を使用して検証ルールを指定します。
db.createCollection( "contacts", { validator: { $or: [ { phone: { $type: "string" } }, { email: { $regex: /@mongodb\.com$/ } }, { status: { $in: [ "Unknown", "Incomplete" ] } } ] } } )
Tip
動作
検証はアップデートや挿入中に行われます。 コレクションに検証を追加すると、変更されるまで既存のドキュメントは検証チェックを受けません。
既存のドキュメントの検証チェックを実行するには、 validateコマンドまたはdb.collection.validate() shellヘルパーを使用します。
既存のドキュメント
validationLevelオプションによって、MongoDB が検証ルールを適用する操作が決まります。
validationLevelがstrict(デフォルト)の場合、MongoDB はすべての挿入とアップデートに検証ルールを適用します。validationLevelがmoderateの場合、MongoDB は、検証条件をすでに満たしている既存のドキュメントの挿入とアップデートに検証ルールを適用します。moderateレベルでは、検証条件を満たさない既存のドキュメントの更新は有効性についてチェックされません。
たとえば、以下のドキュメントでcontactsコレクションを作成する場合、
db.contacts.insert([ { "_id": 1, "name": "Anne", "phone": "+1 555 123 456", "city": "London", "status": "Complete" }, { "_id": 2, "name": "Ivan", "city": "Vancouver" } ])
次のコマンドを発行して、 contactsコレクションにバリデーターを追加します。
db.runCommand( { collMod: "contacts", validator: { $jsonSchema: { bsonType: "object", required: [ "phone", "name" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, name: { bsonType: "string", description: "must be a string and is required" } } } }, validationLevel: "moderate" } )
contactsコレクションにmoderate validationLevel を持つバリデーターが追加されました。
_id: 1を使用してドキュメントを更新しようとした場合、既存のドキュメントが条件に一致しているため、MongoDB は新しい検証ルールを適用します。対照的に、MongoDB は検証ルールを満たしていないため、
_id: 2を含むドキュメントに検証ルールを適用しません。
MongoDB バージョン5.0以降では、検証条件が満たされていない場合、 バリデーターは詳細なエラー情報を返します。 エラー出力は網羅的なもので、最初のエラーだけでなく、すべてのエラーが報告されます。
重要
エラー出力は人間が消費するためのものです。 将来変更される可能性があるため、スクリプトでは依存しないでください。
次の例では、いずれのアップデートも、 nameが string である必要がある検証ルールと整合性がありません。
db.contacts.update( { _id: 1 }, { $set: { name: 10 } } ) db.contacts.update( { _id: 2 }, { $set: { name: 20 } } )
以下の出力は、 errInfoオブジェクトに示されているように、 _id: 1を含むドキュメントが詳細な説明で検証に失敗することを示しています。 このドキュメントは検証追加時に初期基準を満たしていなかったため、 _id: 2を使用したドキュメントの更新に成功します。
// _id: 1 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 121, "errmsg" : "Document failed validation", "errInfo" : { "failingDocumentId" : 1, "details" : { "operatorName" : "$jsonSchema", "schemaRulesNotSatisfied" : [ { "operatorName" : "properties", "propertiesNotSatisfied" : [ { "propertyName" : "name", "details" : [ { "operatorName" : "bsonType", "specifiedAs" : { "bsonType" : "string" }, "reason" : "type did not match", "consideredValue" : 10, "consideredType" : "double" } ] } ] } ] } } } }) // _id: 2 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
検証を完全に無効にするには、 validationLevelをoffに設定します。
無効なドキュメントを受け入れるか拒否する
validationActionオプションは、MongoDB が検証ルールに違反するドキュメントをどのように処理するかを決定します。
validationActionがerror(デフォルト)の場合、MongoDB は検証条件に違反する挿入または更新を拒否します。validationActionがwarnの場合、MongoDB は違反をログに記録しますが、挿入または更新の続行は許可します。
たとえば、次の JSON schema バリデーターを使用してcontacts2コレクションを作成します。
db.createCollection( "contacts2", { validator: { $jsonSchema: { bsonType: "object", required: [ "phone" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, email: { bsonType : "string", pattern : "@mongodb\.com$", description: "must be a string and match the regular expression pattern" }, status: { enum: [ "Unknown", "Incomplete" ], description: "can only be one of the enum values" } } } }, validationAction: "warn" } )
warn validationActionを使用すると、MongoDB はすべての違反をログに記録しますが、挿入または更新を続行できます。
たとえば、次の挿入操作は検証ルールに違反します。
db.contacts2.insertOne( { name: "Amanda", status: "Updated" } )
ただし、 validationActionはwarnのみであるため、MongoDB は検証違反メッセージのみをログに記録し、操作を続行できるようにします。 MongoDB ログを表示するには、次のコマンドを実行します。
db.adminCommand( { getLog: "global" } )
コレクションの使用状況によっては、このコマンドは多くのデータを返す可能性があります。 検証エラー(ログの長い 1 行。読みやすくするためにここで再フォーマットされています)には、次のような情報が含まれています。
"{\"t\":{\"$date\":\"2021-01-20T15:59:57.305+00:00\"}, \"s\":\"W\", \"c\":\"STORAGE\", \"id\":20294, \"ctx\":\"conn1\", \"msg\":\"Document would fail validation\", \"attr\":{\"namespace\":\"test.contacts2\", \"document\":{\"_id\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"name\":\"Amanda\", \"status\":\"Updated\"}, \"errInfo\":{\"failingDocumentId\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"details\":{\"operatorName\":\"$jsonSchema\", \"schemaRulesNotSatisfied\":[ {\"operatorName\":\"properties\", \"propertiesNotSatisfied\":[ {\"propertyName\":\"status\", \"details\":[ {\"operatorName\":\"enum\", \"specifiedAs\":{\"enum\":[ \"Unknown\", \"Incomplete\"]}, \"reason\":\"value was not found in enum\", \"consideredValue\":\"Updated\"}]}]}, {\"operatorName\":\"required\", \"specifiedAs\":{\"required\":[\"phone\"]}, \"missingProperties\":[\"phone\"]}]}}}}"
制限事項
admin、local、および config データベース内のコレクションに対してバリデーターを指定することはできません。
system.* コレクションにバリデーターを指定することはできません。
ドキュメント検証のバイパス
ユーザーはbypassDocumentValidationオプションを使用してドキュメント検証をバイパスできます。
次のコマンドは、新しいオプションbypassDocumentValidationを使用して、操作ごとの検証をバイパスできます。
applyOpsコマンドmapReduceコマンドとdb.collection.mapReduce()メソッドinsertコマンドupdateコマンド$out{ コマンドと メソッドのaggregatedb.collection.aggregate()$merge} ステージと ステージ
アクセス制御が有効になっている配置でドキュメント検証をバイパスするには、認証されたユーザーはbypassDocumentValidationアクションを持っている必要があります。 組み込みロールdbAdminとrestoreはこのアクションを提供します。