Docs Menu
Docs Home
/
MongoDB マニュアル
/ /

クエリ演算子による検証を指定する

項目一覧

  • 制限事項
  • Context
  • 手順
  • 詳細情報
  • 詳細

$eq$gtなどのクエリ演算子を使用して検証を指定し、フィールドを比較できます。

クエリ演算子によるスキーマ検証の一般的なユースケースは、実行時に複数のフィールド値を比較する動的検証ルールを作成する場合です。 たとえば、別のフィールドの値に依存するフィールドがあり、それらの値が互いに正しく比例していることを確認する必要がある場合。

カスタマーの注文を追跡するアプリケーションを考えてみましょう。 注文には基本価格と VATが含まれます。 ordersコレクションには、合計価格を追跡するための次のフィールドが含まれています。

  • price

  • VAT

  • totalWithVAT

次の手順では、クエリ演算子を使用してスキーマ検証を作成し、 totalWithVATpriceVATの予想される組み合わせと一致することを確認します。

1

スキーマ検証を使用してordersコレクションを作成します。

db.createCollection( "orders",
{
validator: {
$expr:
{
$eq: [
"$totalWithVAT",
{ $multiply: [ "$total", { $sum:[ 1, "$VAT" ] } ] }
]
}
}
}
)

この検証では、 totalWithVATフィールドがtotal * (1 + VAT)と等しい場合にのみドキュメントを挿入できます。

2

totalWithVATフィールドが正しい値と等しくないため、次の操作は失敗します。

db.orders.insertOne( {
total: NumberDecimal("141"),
VAT: NumberDecimal("0.20"),
totalWithVAT: NumberDecimal("169")
} )

141 *( 1 + 0.20 )は169.2と等しいため、 totalWithVATフィールドの値は169.2である必要があります。

この操作は、次のエラーを返します。

MongoServerError: Document failed validation
Additional information: {
failingDocumentId: ObjectId("62bcc9b073c105dde9231293"),
details: {
operatorName: '$expr',
specifiedAs: {
'$expr': {
'$eq': [
'$totalWithVAT',
{
'$multiply': [ '$total', { '$sum': [ 1, '$VAT' ] } ]
}
]
}
},
reason: 'expression did not match',
expressionResult: false
}
}
3

ドキュメントを更新して正しいtotalWithVAT値を持つようにすると、操作は成功します。

db.orders.insertOne( {
total: NumberDecimal("141"),
VAT: NumberDecimal("0.20"),
totalWithVAT: NumberDecimal("169.2")
} )

MongoDB は、挿入が成功したことを示す次の出力を返します。

{
acknowledged: true,
insertedId: ObjectId("6304f4651e52f124b84479ba")
}

クエリ演算子の検証とJSON schema の検証を組み合わせることができます。

例として、こちらのスキーマ検証を含む sales コレクションを考えます。

db.createCollection("sales", {
validator: {
"$and": [
// Validation with query operators
{
"$expr": {
"$lt": ["$lineItems.discountedPrice", "$lineItems.price"]
}
},
// Validation with JSON Schema
{
"$jsonSchema": {
"properties": {
"items": { "bsonType": "array" }
}
}
}
]
}
}
)

上記の検証により、sales コレクション内のドキュメントに対して次のルールが強制されます。

  • lineItems.discountedPrice は、lineItems.price 未満である必要があります。このルールは、$lt 演算子を使用して指定されます。

  • items フィールドは配列である必要があります。このルールは、$jsonSchema を使用して指定されます。

戻る

ベストプラクティス