Skip to content

Commit 44c7a02

Browse files
authored
DOCSP-31848: Schema validation (#34)
1 parent 42da0ef commit 44c7a02

File tree

6 files changed

+241
-10
lines changed

6 files changed

+241
-10
lines changed

source/fundamentals.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,22 @@ Fundamentals
99
:maxdepth: 1
1010

1111
/fundamentals/connections
12-
/fundamentals/stable-api
1312
/fundamentals/authentication
1413
/fundamentals/crud
15-
/fundamentals/database-collection
14+
/fundamentals/schema-validation
1615
/fundamentals/aggregation
17-
/fundamentals/tracing-logging
1816
/fundamentals/run-command
1917

2018
..
2119
Connect to MongoDB Atlas from AWS Lambda <https://www.mongodb.com/docs/atlas/manage-connections-aws-lambda/>
20+
/fundamentals/stable-api
2221
/fundamentals/context
22+
/fundamentals/auth
2323
/fundamentals/enterprise-auth
2424
/fundamentals/bson
2525
/fundamentals/indexes
2626
/fundamentals/transactions
27+
/fundamentals/logging
2728
/fundamentals/collations
2829
/fundamentals/monitoring
2930
/fundamentals/gridfs

source/fundamentals/crud/write-operations/change.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ the options available in ``UpdateOptions``:
338338
* - ``bypass_document_validation``
339339
- | If ``true``, allows the driver to perform a write that violates
340340
document-level validation. To learn more about validation, see
341-
:manual:`Schema Validation </core/schema-validation>` in the Server manual.
341+
the guide on :ref:`rust-schema-validation`.
342342

343343
| Type: ``bool``
344344
| Default: ``false``

source/fundamentals/crud/write-operations/insert.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ following table describes the options available in
104104
* - ``bypass_document_validation``
105105
- | If ``true``, allows the driver to perform a write that violates
106106
document-level validation. To learn more about validation, see
107-
:manual:`Schema Validation </core/schema-validation>` in the Server manual.
107+
the guide on :ref:`rust-schema-validation`.
108108

109109
| Type: ``bool``
110110
| Default: ``false``
@@ -124,6 +124,8 @@ following table describes the options available in
124124

125125
| Type: ``Bson``
126126

127+
.. _rust-insertone-bypass-validation-ex:
128+
127129
The following code shows how to construct an ``InsertOneOptions``
128130
instance:
129131

@@ -191,7 +193,7 @@ following table describes the options available in
191193
* - ``bypass_document_validation``
192194
- | If ``true``, allows the driver to perform a write that violates
193195
document-level validation. To learn more about validation, see
194-
:manual:`Schema Validation </core/schema-validation>` in the Server manual.
196+
the guide on :ref:`rust-schema-validation`.
195197

196198
| Type: ``bool``
197199
| Default: ``false``
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
.. _rust-schema-validation:
2+
3+
==================
4+
Schema Validation
5+
==================
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecol
12+
13+
Overview
14+
--------
15+
16+
In this guide, you can learn how to use the {+driver-short+} to implement
17+
**schema validation** for your MongoDB collections.
18+
19+
To implement schema validation, you must provide a JSON schema that consists
20+
of a set of a validation rules. If you implement schema validation, the
21+
server only allows you to run write operations that follow the validation
22+
rules. Use schema validation to restrict data types and value ranges of
23+
document fields in a specified collection.
24+
25+
You can define schema validation rules when creating a collection by using
26+
driver methods, or you can add them to an existing collection by using the
27+
``collMod`` MongoDB command. This guide only describes how to enable schema
28+
validation when creating a collection. To learn more about enabling schema
29+
validation on existing collections, see :manual:`collMod </reference/command/collMod/>`
30+
in the Server manual.
31+
32+
.. _rust-json-validation:
33+
34+
JSON Schema Validation
35+
----------------------
36+
37+
Before creating a collection with schema validation rules, you must define a
38+
JSON schema.
39+
40+
The JSON schema is a JSON object that contains key-value pairs specifying
41+
the validation rules for your collection. At the top level, this object must
42+
include a ``$jsonSchema`` object. The ``$jsonSchema`` object includes the
43+
following fields:
44+
45+
- **title**: sets an optional description for the schema.
46+
- **required**: specifies a list of required fields for each document in
47+
your collection.
48+
- **properties**: sets property requirements for individual fields.
49+
50+
For a full list of JSON schema object fields, see :manual:`JSON Schema
51+
</reference/operator/query/jsonSchema/#json-schema>` in the Server manual.
52+
53+
Implement Schema Validation
54+
---------------------------
55+
56+
You can implement schema validation by passing your schema and related options
57+
in an instance of ``CreateCollectionOptions`` to the ``create_collection()``
58+
method. You can build a ``CreateCollectionOptions`` instance by using the
59+
``CreateCollectionOptions::builder()`` method.
60+
61+
Call the following ``CreateCollectionOptions::builder()`` functions to specify
62+
the validation options for the new collection:
63+
64+
.. list-table::
65+
:widths: 30 70
66+
:header-rows: 1
67+
68+
* - Method
69+
- Description
70+
71+
* - ``validator()``
72+
- Specifies validation rules for a collection by passing a JSON schema.
73+
74+
For more information, see the :ref:`<rust-json-validation>`
75+
section on this page.
76+
77+
* - ``validation_level()``
78+
- Specifies which insert and update operations are subject to the validation
79+
rules.
80+
81+
Possible values: ``ValidationLevel::Off``,
82+
``ValidationLevel::Strict``, ``ValidationLevel::Moderate``.
83+
84+
* - ``validation_action()``
85+
- Specifies whether the driver throws an error or a warning if you insert documents
86+
that don't follow the validation rules.
87+
88+
Possible values: ``ValidationAction::Error``, ``ValidationAction::Warn``.
89+
90+
Example
91+
~~~~~~~
92+
93+
This example creates a collection called ``survey_answers`` with the
94+
following validation specifications:
95+
96+
- The ``validator()`` method recieves a JSON schema specifying that the
97+
``answer`` field in each document must have a value of ``"yes"`` or
98+
``"no"``.
99+
- The ``validation_action()`` method specifies whether the driver raises an
100+
``Error`` when a write operation violates a validation rule.
101+
- The ``validation_level()`` method specifies that the validation is
102+
``Moderate``, so the validation rules apply only to inserts and
103+
updates on existing valid documents.
104+
105+
.. literalinclude:: /includes/fundamentals/code-snippets/schema-validation.rs
106+
:language: rust
107+
:dedent:
108+
:start-after: begin-schema-validation
109+
:end-before: end-schema-validation
110+
111+
The following documents follow the validation rules and can be successfully
112+
inserted:
113+
114+
.. code-block:: json
115+
:copyable: false
116+
:emphasize-lines: 4, 9
117+
118+
{
119+
"_id": { ... },
120+
"question": "Do you like to exercise?",
121+
"answer": "yes"
122+
},
123+
{
124+
"_id": { ... },
125+
"question": "Do you like to play computer games?",
126+
"answer": "no"
127+
}
128+
129+
However, if you attempt to insert the following document, the server
130+
raises an error because the value of ``answer`` does not match any of
131+
the valid options:
132+
133+
.. io-code-block::
134+
:copyable: false
135+
136+
.. input::
137+
:language: json
138+
:emphasize-lines: 4
139+
140+
{
141+
"_id": { ... },
142+
"question": "Do you like to exercise?",
143+
"answer": "depends on my mood"
144+
}
145+
146+
.. output::
147+
:language: none
148+
:visible: false
149+
150+
Error: Error { kind: Write(WriteError(WriteError { code: 121, code_name:
151+
None, message: "Document failed validation", details:
152+
Some(Document({"failingDocumentId":
153+
ObjectId("..."), "details":
154+
Document({"operatorName": String("$jsonSchema"), "title": String("Answer
155+
Value Validation"), ... })})) })), ... }
156+
157+
.. tip:: Bypass Schema Validation
158+
159+
To bypass a collection's validation rules, set the ``bypass_document_validation``
160+
field to ``true`` in the write method's options parameter. This ignores any validation
161+
rules on the collection and any exemptions of them defined by the ``validation_level``.
162+
163+
To see an example of how to specify this setting in the options for the
164+
``insert_one()`` method, see the :ref:`Modify insert_one Behavior
165+
<rust-insertone-bypass-validation-ex>` section of the Insert Documents guide.
166+
167+
Additional Information
168+
----------------------
169+
170+
To learn more about the MongoDB Server operations mentioned on this page,
171+
see the following Server manual documentation:
172+
173+
- :manual:`Validation operations for the collMod command </reference/command/collMod/#validate-documents>`
174+
- :manual:`Schema Validation </core/schema-validation/>`
175+
- :manual:`Specify JSON Schema Validation </core/schema-validation/specify-json-schema/#std-label-schema-validation-json>`
176+
177+
API Documentation
178+
~~~~~~~~~~~~~~~~~
179+
180+
To learn more about setting validation levels and actions, see the
181+
following API Documentation:
182+
183+
- `validation_level <{+api+}/options/struct.CreateCollectionOptions.html#structfield.validation_level>`__
184+
for the ``validation_level()`` helper method
185+
- `ValidationLevel <{+api+}/options/enum.ValidationLevel.html>`__ for possible ``validation_level`` values
186+
- `validation_action <{+api+}/options/struct.CreateCollectionOptions.html#structfield.validation_action>`__
187+
for the ``validation_action()`` helper method
188+
- `ValidationAction <{+api+}/options/enum.ValidationAction.html>`__ for possible ``validation_action`` values
189+
190+
To learn more about any other methods or types referenced in this
191+
guide, see the following documentation:
192+
193+
- `create_collection() <{+api+}/struct.Database.html#method.create_collection>`__
194+
- `CreateCollectionOptions <{+api+}/options/struct.CreateCollectionOptions.html>`__
195+
- `validator <{+api+}/options/struct.CreateCollectionOptions.html#structfield.validator>`__

source/includes/fundamentals-sections.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ Learn how to perform the following tasks using the {+driver-short+} in the
22
Fundamentals section:
33

44
- :ref:`Connect to MongoDB <rust-connection>`
5-
- :ref:`Specify the {+stable-api+} Version <rust-stable-api>`
6-
- :ref:`Authenticate to MongoDB <rust-authentication>`
75
- :ref:`Read from and Write to MongoDB <rust-crud>`
8-
- :ref:`Manage Databases and Collections <rust-db-coll>`
6+
- :ref:`Implement Schema Validation <rust-schema-validation>`
97
- :ref:`Perform Aggregations <rust-aggregation>`
10-
- :ref:`Record Driver Events <rust-tracing-logging>`
118
- :ref:`Run A Database Command <rust-run-command>`
129

1310
..
@@ -18,6 +15,7 @@ Fundamentals section:
1815
- :ref:`Convert Data to and from BSON <rust-bson>`
1916
- :ref:`Construct Indexes <rust-indexes>`
2017
- :ref:`Specify Collations to Order Results <rust-collations>`
18+
- :ref:`Record Log Messages <rust-logging>`
2119
- :ref:`Monitor Driver Events <rust-monitoring>`
2220
- :ref:`Store and Retrieve Large Files by Using GridFS <rust-gridfs>`
2321
- :ref:`Use a Time Series Collection <rust-time-series>`
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use bson::{ Document };
2+
use mongodb::{ bson::doc, options::{ CollectionOptions, WriteConcern }, Client, Collection };
3+
use std::env;
4+
5+
#[tokio::main]
6+
async fn main() -> mongodb::error::Result<()> {
7+
let uri = "<connection string>";
8+
let client = Client::with_uri_str(uri).await?;
9+
10+
let db: mongodb::Database = client.database("test_db");
11+
12+
// begin-schema-validation
13+
let validator =
14+
doc! {
15+
"$jsonSchema": doc! {
16+
"bsonType": "object",
17+
"title": "Answer Value Validation",
18+
"properties": doc! {
19+
"answer": doc! {
20+
"enum": vec! [ "yes", "no" ],
21+
}
22+
}
23+
}
24+
};
25+
let validation_opts = CreateCollectionOptions::builder()
26+
.validator(validator)
27+
.validation_action(Some(ValidationAction::Error))
28+
.validation_level(Some(ValidationLevel::Moderate))
29+
.build();
30+
31+
db.create_collection("survey_answers", validation_opts).await?;
32+
// end-schema-validation
33+
34+
Ok(())
35+
}

0 commit comments

Comments
 (0)