Docs Menu
Docs Home
/
データベース マニュアル
/ /

多形コレクションの検証を指定する

多形データ を保存するコレクション、またはさまざまな構造またはスキーマを持つコレクションに対してスキーマ検証を指定できます。

単一のコレクション内に複数のスキーマのスキーマ検証を作成するには、検証ルールでスキーマを設定し、ドキュメントがコレクションのスキーマの 1 つに準拠していることを確認します。

accounts金融機関の顧客とそのアカウント詳細に関するデータを保存するコレクション、 について考えてみましょう。コレクションにはcustomer ドキュメントとaccount ドキュメントの両方が含まれています。

次のコードでは、2customer つの ドキュメントをaccounts コレクションに挿入して、それぞれ と の詳細を保存します。また、個々の保存アカウントを表すために 2account つの ドキュメントと、共有のチェックアカウントを表す 3account 番目の ドキュメントも挿入されます。このチュートリアルのコードは、 MongoDB Shell(mongosh)で実行できます。

db.accounts.insertMany( [
{
"customerId": "CUST-123456789",
"docType": "customer",
"name": {
"title": "Mr",
"first": "Andrew",
"middle": "James",
"last": "Morgan"
},
"address": {
"street1": "240 Blackfriars Rd",
"city": "London",
"postCode": "SE1 8NW",
"country": "UK"
},
"customerSince": ISODate("2005-05-20")
},
{
"customerId": "CUST-987654321",
"docType": "customer",
"name": {
"title": "Mrs",
"first": "Anne",
"last": "Morgan"
},
"address": {
"street1": "240 Blackfriars Rd",
"city": "London",
"postCode": "SE1 8NW",
"country": "UK"
},
"customerSince": ISODate("2003-12-01")
},
{
"accountNumber": "ACC1000000654",
"docType": "account",
"accountType": "checking",
"customerId": [
"CUST-123456789",
"CUST-987654321"
],
"dateOpened": ISODate("2003-12-01"),
"balance": Decimal128("5067.65")
},
{
"accountNumber": "ACC1000000432",
"docType": "account",
"accountType": "savings",
"customerId": [
"CUST-123456789"
],
"dateOpened": ISODate("2005-10-28"),
"balance": Decimal128("10341.21")
},
{
"accountNumber": "ACC1000000890",
"docType": "account",
"accountType": "savings",
"customerId": [
"CUST-987654321"
],
"dateOpened": ISODate("2003-12-15"),
"balance": Decimal128("10341.89")
}
] );

customer または account スキーマに準拠するドキュメントのみを accountsコレクションに許可するには、次の手順を使用してスキーマ検証を設定します。

1

異なるタイプのドキュメントを区別するために、複数のJSONスキーマを使用できます。ドキュメントに含める必要がある属性と、それらが受け入れるデータ型を定義するには、 customerドキュメント用に 1 つ、accountドキュメント用に 1 つのスキーマを作成します。各スキーマには、表すエンティティのタイプを識別するための docType 属性が含まれています。

const customerSchema = {
required: ["docType", "customerId", "name", "customerSince"],
properties: {
docType: { enum: ["customer"] },
customerId: { bsonType: "string"},
name: {
bsonType: "object",
required: ["first", "last"],
properties: {
title: { enum: ["Mr", "Mrs", "Ms", "Dr"]},
first: { bsonType: "string" },
middle: { bsonType: "string" },
last: { bsonType: "string" }
}
},
address: {
bsonType: "object",
required: ["street1", "city", "postCode", "country"],
properties: {
street1: { bsonType: "string" },
street2: { bsonType: "string" },
postCode: { bsonType: "string" },
country: { bsonType: "string" }
}
},
customerSince: {
bsonType: "date"
}
}
};
const accountSchema = {
required: ["docType", "accountNumber", "accountType", "customerId", "dateOpened", "balance"],
properties: {
docType: { enum: ["account"] },
accountNumber: { bsonType: "string" },
accountType: { enum: ["checking", "savings", "mortgage", "loan"] },
customerId: { bsonType: "array" },
dateOpened: { bsonType: "date" },
balance: { bsonType: "decimal" }
}
};
2

customerSchemaaccountSchemaoneOfまたは のいずれかに一致するドキュメントを許可するには、 JSON スキーマ演算子を使用します。次に、collMod コマンドを使用して、使用するaccounts コレクションをスキーマ検証に更新します。

db.runCommand({
collMod: "accounts",
validator: { $jsonSchema: { oneOf: [ customerSchema, accountSchema ] } }
})
3

オプションで、セマンティック検証を追加できます。例、コレクションのドキュメントに次の制約を追加できます。

  • customer ドキュメントの場合、customerSince 値は現在の時刻より前の時刻にはできません。

  • account ドキュメントの場合、dateOpened 値は現在の時刻より前の時刻にはできません。

  • 節約アカウントの場合、balance は 0 を下回ることはできません。

無効な customer ドキュメントと account ドキュメントを識別し、それらの制約をスキーマ検証に実装することで、追加の検証を実装できます。

const invalidCustomer = {
"$expr": { "$gt": ["$customerSince", "$$NOW"] }
};
const invalidAccount = {
$or: [
{
accountType: "savings",
balance: { $lt: 0}
},
{
"$expr": { "$gt": ["$dateOpened", "$$NOW"]}
}
]
};
const schemaValidation = {
"$and": [
{ $jsonSchema: { oneOf: [ customerSchema, accountSchema ] }},
{ $nor: [
invalidCustomer,
invalidAccount
]
}
]
};
db.runCommand({
collMod: "accounts",
validator: schemaValidation
})
4

コレクションにすでにあるすべてのドキュメントが新しいスキーマ検証に準拠していることを確認するには、db.collection.validate() コマンドを使用します。

db.accounts.validate()
{
ns: '66cf8508e64dbb03ce45b30e_test.accounts',
uuid: UUID('1aedf62a-f202-4e7c-b434-879057bb6d6b'),
nInvalidDocuments: 0,
nNonCompliantDocuments: 0,
nrecords: 10,
nIndexes: 1,
keysPerIndex: { _id_: 10 },
indexDetails: { _id_: { valid: true } },
valid: true,
repaired: false,
readTimestamp: Timestamp({ t: 1749235730, i: 26 }),
warnings: [],
errors: [],
extraIndexEntries: [],
missingIndexEntries: [],
corruptRecords: [],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1749235753, i: 31 }),
signature: {
hash: Binary.createFromBase64('3h7qyhLsgU21Pnzf/KVLl8suu2I=', 0),
keyId: Long('7449048397505364002')
}
},
operationTime: Timestamp({ t: 1749235753, i: 31 })
}

nNonCompliantDocuments: 0 出力の は、accountsコレクション内のすべてのドキュメントがコレクションスキーマに準拠していることを示します。

5

スキーマ検証を確認するには、 accountsコレクションに無効なドキュメントを挿入してみてください。例、姓に必須の lastフィールドが欠落している customerドキュメントを挿入してみてください。

db.accounts.insertOne(
{
"docType": "customer",
"customerId": "12345",
"name": {
"first": "John",
},
"customerSince": "2025-01-01T00:00:00Z"
}
)
MongoServerError: Document failed validation

戻る

ベストプラクティス

項目一覧