diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java
index f65814850..f837c0bfb 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java
@@ -23,6 +23,37 @@ import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.Object
import org.springframework.util.Assert;
/**
+ * Interface defining MongoDB-specific JSON schema object. New objects can be built with {@link #builder()}, for
+ * example:
+ *
+ *
+ * MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname")
+ * .properties(string("firstname").possibleValues("luke", "han"),
+ * object("address").properties(string("postCode").minLength(4).maxLength(5))
+ *
+ * ).build();
+ *
+ *
+ * resulting in the following schema:
+ *
+ *
+ * {
+ "type": "object",
+ "required": [ "firstname", "lastname" ],
+ "properties": {
+ "firstname": {
+ "type": "string", "enum": [ "luke", "han" ],
+ },
+ "address": {
+ "type": "object",
+ "properties": {
+ "postCode": { "type": "string", "minLength": 4, "maxLength": 5 }
+ }
+ }
+ }
+}
+ *
+ *
* @author Christoph Strobl
* @since 2.1
**/
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index ec3fbeaf2..526c23478 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -5,8 +5,8 @@
== What's new in Spring Data MongoDB 2.1
* Cursor-based aggregation execution.
* <> for imperative and reactive Template API.
-* `validator` support for collections.
-* `$jsonSchema` support for queries.
+* <>.
+* <> for queries and collection creation.
[[new-features.2-0-0]]
== What's new in Spring Data MongoDB 2.0
diff --git a/src/main/asciidoc/reference/mongo-3.adoc b/src/main/asciidoc/reference/mongo-3.adoc
index 3ab427b4d..281a63a60 100644
--- a/src/main/asciidoc/reference/mongo-3.adoc
+++ b/src/main/asciidoc/reference/mongo-3.adoc
@@ -81,6 +81,21 @@ In order to use authentication with XML configuration use the `credentials` attr
----
+[[mongo.mongo-3.validation]]
+=== Server-side Validation
+
+MongoDB supports https://docs.mongodb.com/manual/core/schema-validation/[Schema Validation] as of version 3.2 with query operators
+and as of version 3.6 JSON-schema based validation.
+
+This chapter will point out the specialties for validation in MongoDB and how to apply JSON schema validation.
+
+[[mongo.mongo-3.validation.json-schema]]
+==== JSON Schema Validation
+
+MongoDB 3.6 allows validation and querying of documents using JSON schema draft 4 including core specification and validation specification, with some differences. `$jsonSchema` can be used in a document validator (when creating a collection), which enforces that inserted or updated documents are valid against the schema. It can also be used to query for documents with the `find` command or `$match` aggregation stage.
+
+Spring Data MongoDB supports MongoDB's specific JSON schema implementation to define and use schemas. See <> for further details.
+
[[mongo.mongo-3.misc]]
=== Other things to be aware of
diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc
index 9ee53cab9..38f757e13 100644
--- a/src/main/asciidoc/reference/mongodb.adoc
+++ b/src/main/asciidoc/reference/mongodb.adoc
@@ -1054,6 +1054,8 @@ As you can see most methods return the `Criteria` object to provide a fluent sty
* `Criteria` *regex* `(String re)` Creates a criterion using a `$regex`
* `Criteria` *size* `(int s)` Creates a criterion using the `$size` operator
* `Criteria` *type* `(int t)` Creates a criterion using the `$type` operator
+* `Criteria` *matchingDocumentStructure* `(MongoJsonSchema schema)` Creates a criterion using the `$jsonSchema` operator for <>. `$jsonSchema` can only be applied on the top level of a query and not property specific. Use the `properties` attribute of the schema to match against nested fields.
+
There are also methods on the Criteria class for geospatial queries. Here is a listing but look at the section on <> to see them in action.
@@ -1467,7 +1469,65 @@ WARNING: Indexes are only used if the collation used for the operation and the i
[[mongo.jsonSchema]]
=== JSON Schema
-As of version 3.6 MongoDB supports collections that validate ``Document``s against a provided JSON Schema. The schema itself and both validation action and level can be defined when creating the collection.
+As of version 3.6 MongoDB supports collections that validate ``Document``s against a provided JSON Schema.
+The schema itself and both validation action and level can be defined when creating the collection.
+
+.Sample JSON schema
+====
+[source,json]
+----
+{
+ "type": "object", <1>
+
+ "required": [ "firstname", "lastname" ], <2>
+
+ "properties": { <3>
+
+ "firstname": { <4>
+ "type": "string",
+ "enum": [ "luke", "han" ]
+ },
+ "address": { <5>
+ "type": "object",
+ "properties": {
+ "postCode": { "type": "string", "minLength": 4, "maxLength": 5 }
+ }
+ }
+ }
+}
+----
+<1> JSON schema documents always describe a whole document from its root. A schema is a schema object itself that can contain
+embedded schema objects describing properties and subdocuments.
+<2> `required` is a property describing which properties are required in a document. It can be specified optionally along of other
+schema constraints. See MongoDB's documentation on https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/#available-keywords[available keywords].
+<3> `properties` is related to a schema object describing an `object` type. It contains property-specific schema constraints.
+<4> `firstname` specifies constrains for the `firsname` field inside the document. Here it's a string-based properties declaring
+ possible field values.
+<5> `address` is a subdocument defining a schema for values in its `postCode` field.
+====
+
+You can provide a schema either by specifying a schema document (i.e. using the `Document` API by parsing or building a document object) or by building it with Spring Data's JSON schema utilities in `org.springframework.data.mongodb.core.schema`. `MongoJsonSchema` is the entry point for all JSON schema-related operations.
+
+.Creating a JSON schema
+====
+[source,java]
+----
+MongoJsonSchema.builder() <1>
+ .required("firstname", "lastname") <2>
+
+ .properties(
+ string("firstname").possibleValues("luke", "han"), <3>
+
+ object("address")
+ .properties(string("postCode").minLength(4).maxLength(5)))
+
+ .build(); <4>
+----
+<1> Obtain a schema builder to configure the schema with a fluent API.
+<2> Configure required properties.
+<3> Configure the String-typed `firstname` field allowing only `luke` and `han` values. Properties can be typed or untyped. Use a static import of `JsonSchemaProperty` to make the syntax slightly more compact and to get entrypoints like `string(…)`.
+<4> Build the schema object. Use the schema to either create a collection or <>.
+====
`CollectionOptions` provides the entry point to schema support for collections.
@@ -1475,21 +1535,100 @@ As of version 3.6 MongoDB supports collections that validate ``Document``s again
====
[source,java]
----
-// TODO: add sample here!
+MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
+
+template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
----
====
-Additionally it is also possible to query any collection for documents that match a given structure defined by a JSON Schema.
+You can use a schema to query any collection for documents that match a given structure defined by a JSON schema.
-.Query collation for Documents matching a `$jsonSchema`
+.Query for Documents matching a `$jsonSchema`
====
[source,java]
----
-// TODO: add sample here!
+MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
+
+template.find(query(matchingDocumentStructure(schema)), Person.class);
----
====
-NOTE: `$jsonSchema` can only be applied on the top level of a query and not property specific. Use the `properties` attribute of the schema to match against nested fields.
+[cols="3,1,6", options="header"]
+.Supported JSON schema types
+|===
+| Schema Type
+| Java Type
+| Schema Properties
+
+| `untyped`
+| -
+| `description`, generated `description`, `enum`, `allOf`, `anyOf`, `oneOf`, `not`
+
+| `object`
+| `Object`
+| `required`, `additionalProperties`, `properties`, `minProperties`, `maxProperties`, `patternProperties`
+
+| `array`
+| any array except `byte[]`
+| `uniqueItems`, `additionalItems`, `items`, `minItems`, `maxItems`
+
+| `string`
+| `String`
+| `minLength`, `maxLentgth`, `pattern`
+
+| `int`
+| `int`, `Integer`
+| `multipleOf`, `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum`
+
+| `long`
+| `long`, `Long`
+| `multipleOf`, `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum`
+
+| `double`
+| `float`, `Float`, `double`, `Double`
+| `multipleOf`, `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum`
+
+| `decimal`
+| `BigDecimal`
+| `multipleOf`, `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum`
+
+| `number`
+| `Number`
+| `multipleOf`, `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum`
+
+| `binData`
+| `byte[]`
+|
+
+| `boolean`
+| `boolean`, `Boolean`
+|
+
+| `null`
+| `null`
+|
+
+| `objectId`
+| `ObjectId`
+|
+
+| `date`
+| `java.util.Date`
+|
+
+| `timestamp`
+| `BsonTimestamp`
+|
+
+| `regex`
+| `java.util.regex.Pattern`
+|
+
+|===
+
+NOTE: `untyped` is a generic type that is inherited by all typed schema types providing all `untyped` schema properties to typed schema types.
+
+For more information, see https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/#op._S_jsonSchema[$jsonSchema].
[[mongo.query.fluent-template-api]]
=== Fluent Template API