MongoDB 3.2 になって、ドキュメントバリデーション機能が追加されましたので、説明します。
コレクションを作る時に、バリデーションをかける方法
例えばhogeコレクションのnameというキーの値を文字列に限定したい場合は、以下の様にします。
> db.createCollection( "user" , {
validator : {
name : { $type : "string" },
age : { $gt : "number" }
},
validationLevel: "strict", # ←省略可
validationAction: "error" # ←省略可
})
そうすると、正しいドキュメントは入りますが、
> db.user.insert({"name":"fetaro","age":33})
WriteResult({ "nInserted" : 1 })
以下の様にnameに数字を入れると怒られます。エラーメッセージは"Document failed validation"で固定です。
> db.user.insert({"name":1,"age":1})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
バリデーションの変更
バリデーションを変更したり、既存のコレクションにバリデーションを後からかける場合は、runCommandを使います(たぶんこれしか方法が無い)
db.runCommand({
"collMod" : "user" ,
"validator" : {
name : { $type : "string" },
age : { $gt : 0 }
} } )
バリデーションの確認
バリデーションの定義はdb.getCollectionInfos()をたたくと見れます。かなり大雑把なつくりです。。。
> db.getCollectionInfos()
[
{
"name" : "user",
"options" : {
"validator" : {
"name" : {
"$type" : "string"
},
"age" : {
"$gt" : 0
}
},
"validationLevel" : "strict",
"validationAction" : "error"
}
}
]
バリデーションの内容 (validator)
バリデーションの内容の定義は、find()などで条件を指定するときに使う表現がほぼそのまま使えます。
文法としては、
キー名 : { (バリデーションの種類) : (バリデーションの値) }
です。例えば
"name" : { "$type" : "string"}
といった感じです。よく使うバリデーションの種類は以下でしょう。
バリデーションの種類 | 説明 | バリデーションの値 |
---|---|---|
$exists |
キーが存在するか |
true ,false
|
$type |
値の型が正しいか | "number","string" 等 |
$in |
値が配列に含まれるか | 想定するキーの値を含む配列 |
$regex |
値が正規表現とマッチするか | 正規表現 |
その他のバリデーションの種類については、find()などの条件指定方法と同じであるため、以下を参照してください。
ただし$near
, $nearSphere
, $text
, $where
は使えません。
また、配列かどうかをバリデーションしたい場合は
db.createCollection("user" , { validator : { "hoge" : {$type : "array" }}})
ではなく
db.createCollection("user" , { validator : { "hoge.0" : {$exists : true}}})
としないといけないため、注意が必要です。
バリデーションのレベル(validationLevel)
以下の二つがあります。
- strict : 全ての挿入と更新が対象になる (デフォルト)
- moderate : 挿入と、既存の正しいドキュメントに対しての更新が対象になる。既存の正しくないドキュメントは対象にならない。
正しくないドキュメントを検出したときの動き(validationAction)
以下の二つがあります。
- error : ドキュメントの挿入・更新に失敗する (デフォルト)
- warn : ドキュメントの挿入・更新は成功するが、ログに以下のような警告が出る
2016-04-26T00:58:01.200+0900 W STORAGE [conn7] Document would fail validation collection: test.user doc: { _id: ObjectId('571e3e8904949114afa69d29'), name: 1.0, age: 1.0 }
参考
Validationについて書いた公式ドキュメントは情報不足なので、createCollectionのマニュアルを読むことをお勧めします。→ https://docs.mongodb.org/manual/reference/method/db.createCollection/
所感
省エネで作ったという感触を受けます。エラーメッセージは固定文言ですし、コマンドはほぼ生コマンド、チェックロジックも条件検索の使いまわしです(まあ、それで十分ですが)。