Docs Menu
Docs Home
/
데이터베이스 매뉴얼
/ /

다형성 컬렉션에 대한 유효성 검사 지정

다형성 데이터를 저장하는 컬렉션 또는 다양한 구조나 스키마를 가진 문서에 대해 스키마 유효성 검사 지정할 수 있습니다.

단일 컬렉션 내에서 여러 스키마에 대한 스키마 유효성 검사 만들려면 유효성 검사 규칙에서 스키마를 설정하다 하고 문서가 컬렉션의 스키마 중 하나를 준수하는지 확인할 수 있습니다.

은행 고객에 대한 데이터와 해당 고객의 계정 세부 정보를 저장하는 컬렉션accounts이 있다고 가정해 보겠습니다. 컬렉션 에 customer 문서와 account 문서가 모두 포함되어 있습니다.

다음 코드는 customer 컬렉션 에 두 개의 문서를 삽입하여 accounts 고객인 앤드류와 앤의 세부 정보를 각각 저장 . 또한 account 각 개인의 저축 계좌를 나타내는 두 개의 문서와 공유 당좌예금 계좌를 나타내는 세 번째 문서 account 삽입합니다. 이 튜토리얼의 코드는 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 schema를 사용할 수 있습니다. 문서 에 포함되어야 하는 속성과 허용하는 데이터 유형을 정의하려면 customer 문서 용 스키마와 account 문서 용 스키마 두 가지를 만듭니다. 각 스키마 나타내는 엔터티 유형을 식별하는 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

또는 와 일치하는 문서를 허용하려면 customerSchema accountSchema oneOf JSON schema 연산자 사용합니다. 그런 다음 collMod 명령을 사용하여 스키마 accounts 유효성 검사 에 사용할 컬렉션 업데이트 .

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

선택적으로 시맨틱 예비 검사를 추가할 수 있습니다. 예시 들어 컬렉션의 문서에 다음 제약 조건을 추가할 수 있습니다.

  • customer 문서의 경우 customerSince 값은 현재 시간보다 이전일 수 없습니다.

  • account 문서의 경우 dateOpened 값은 현재 시간보다 이전일 수 없습니다.

  • 절약 계정의 경우 balance 은(는) 0 아래로 떨어질 수 없습니다.

유효하지 않은 customeraccount 문서를 식별하고 이러한 제약 조건을 스키마 유효성 검사 에 구현하여 예비 유효성 검사를 구현 수 있습니다.

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

돌아가기

모범 사례

이 페이지의 내용