Navigation

MongoDB Service Validation

For a MongoDB Service, you can specify validation rules for update and insert operations. If the update and insert operations do not pass the validation rule, MongoDB Stitch fails the operations.

MongoDB Document Validataion

MongoDB Stitch validation rules do not override the document validation that may have been set up separately in MongoDB.

Default Validation Rule

To view the validation rule:

  1. Click on your MongoDB Atlas cluster under Atlas Clusters in the left navigation pane.
  2. Click on the Rules tab.
  3. Click on the MonogoDB Collection for which you wish to view rules.
  4. Click on the Top-Level Document in the Field Rules view.

By default, the collection has the following validation rule specified on the owner_id field that determines whether a write operation is permissible:

{
  "%or": [
    { "%%prev": "%%user.id" },
    { "%%prev": { "%exists": false } }
  ]
}

With this rule, a write operation is valid if either:

  • The write operation modifies a document where the value of owner_id previous to the write operation (%%prev) equals the user ID (%%user.id) of the client issuing the write. An example of this kind of write operation is a client modifying a document that it previously inserted, or
  • The write operation modifies a document where there was no value for the owner_id field (%exists) previous to the write operation (%%prev). An example of this kind of write operation is an insert of a new document.

Validation Rules Syntax

You can specify rules as JSON documents. MongoDB query expression operators (with the exception of the $text and the geospatial operators) are available for rule expressions.

{
  <field1>: <value1|expression1>,
  <field2>: <value2|expression2>,
  ...
}

To access elements of an array or access fields in an embedded document, use dot notation. For list of MongoDB query operators available, see Query Selectors.

You can also preface the <field> name with an expansion (%%<keyword>):

{
  "<expansion>.<field1>":  <value1|expression1>,
  "<expansion>.<field2>":  <value2|expression2>,
  ...
}

Tip

  • When a field is referenced at the top-level of a document rule, a field name <field> without any expansion is shorthand for %%root.<field>. In a validation rule, %%root refers to the document after the write operation.

    However , if a compound rule includes nested expressions, you must explicitly include the expansion for a field in the nested expressions. For example:

    {
       "%or": [
          { "%%this.views": { "%gt": 0 } },
          { "%%prev.views": { "%exists": 0 } } ]
    }
    
  • When specifying a rule at a field level, you can use %%this to refer to the field; e.g., { "%%this": <value> }.

    • In a validation rule for a document, %%this refers to the document after the write operation.
    • In a validation rule for a field, %%this refers to the field after the write operation.
  • For more information on MongoDB Stitch expansions see Expansions.

The following table lists some syntax examples:

Syntax Examples Description
{} An empty JSON document evaluates to true. If specified as a document rule, all documents satisfy this validation rule. If specified as a field rule, the field is always valid.
{ "%%true": true } The expression always evaluates to true as the value of the expansion %%true equals the boolean true. If specified as a document rule, all documents satisfy this validation rule. If specified as a field rule, the field is always valid.
{ "%%true": false } The expression always evaluates to false as the reserved expansion value %%true does not equal the boolean false. If specified as a document rule, no document satisfies this validation rule. If specified as a field rule, the field is never valid.
{
  "<field1>": <value1|exp1>,
  "<field2>": <value2|exp2>,
  ...
}

or

{
   "<expansion1>.<field1>": <value1|exp1>,
   "<expansion2>.<field2>": <value2|exp2>,
   ...
}
The compound document/field rule evaluates to true if all conditions are satisfied.
{
  "%or": [
     { "<expansion>.<field1>": <value1|exp1> },
     { "<expansion>.<field2>": <value2|exp2> },
     ...
  ]
}

The compound document/field rule evaluates to true if any of the specified conditions is satisfied.

Note

You must include expansions %%<keyword> to reference fields in the nested rule expressions.

Validation Rule Example

The validation rule example below applies to insert/update operations on the collection reports with the following documents:

{
   "_id" : 1,
   "title" : "Pies",
   "about" : { "subject" : "pies", "counts" : { "pages" : 5, "words" : 100 } },
   "type" : "Public",
   "views" : 101
}
{
   "_id" : 2,
   "title" : "Pastries Part 1",
   "about" : { "subject" : "puff pastries", "counts" : { "pages" : 50, "words" : 5000 } },
   "type" : "Public",
   "views" : 21
}
{
  "_id" : 3,
  "title" : "Cakes",
  "about" : { "subject" : "cupcakes", "counts" : { "pages" : 1, "words" : 200 } },
  "type" : "Internal",
  "views" : 50
 }

To ensure that all documents inserted or updated in the reports collection have:

  • type field with one of two values, "Public" or "Internal", and
  • about.counts.words field contains contains a number greater than 0.

You can specify the following validation rule at the document level:

{
  "type": { "%in": [ "Public", "Internal" ] },
  "about.counts.words": { "%type": "number", "%gt": 0 }
}

This validation rule would disallow any insert or update opertions that results in documents that do not violate the rule. For example, the following insert operation would fail:

db.reports.insert(
   {
     "title" : "",
     "about" : { "subject" : "", "counts" : { "pages" : 1, "words" : 0 } },
     "type" : "Public",
     "views" : 50
   }
)

You could specify the above validation rule as separate field level validation rules for the type field and about.counts.words field. That is,

  • The type field has the following validation rule:

    {
      "%%this": { "%in": [ "Public", "Internal" ] }
    }
    
  • The about.counts.words field has the following validation rule:

    {
      "%%this": { "%type": "number", "%gt": 0 }
    }
    

Validation Rules and Write Rules

Delete Operations

Validation rules apply for insert and update operations only. Write rules apply to insert, update, and delete operations.

Rule Cascade

Unlike a write rule where the rule at the highest level overrides any rule specified at a lower level, validation rules do not propagate down to lower levels. That is, if a document validation rule and field validation rule exist, the document validation rule has no implication for the field validation.

For example, if the following document-level validation rule exists:

{
  "about.counts.words": { "%exists": 1 }
}

And, the following field-level validation rule exists for the about.counts.words field:

{
  "%%this": {
    "%type": "number",
    "%gt": 0
  }
}

The following insert operation will fail because it fails the field level validation rule even though it passes the document level validation rule:

{
   "title" : "Brioche",
   "about" : { "subject" : "breads", "counts" : { "pages" : 10, "words" : 0 } },
   "type" : "Public",
   "views" : 50
}