@@ -937,3 +937,78 @@ modified by a user with the ``_admin`` role:
937937 CouchDB Guide:
938938 - `Validation Functions
939939 <http:// guide.couchdb.org/editions/1/en/validation.html>`_
940+
941+ Validation using Mango selectors
942+ --------------------------------
943+
944+ The ``validate_doc_update`` field may be written as a :ref:`Mango selector
945+ <find/selectors>`, instead of as a JavaScript function . This provides greater
946+ performance since documents do not need to be sent to an external process for
947+ validation, but is more restrictive in terms of what kinds of validation rules
948+ can be expressed. Mango selectors can express declarative rules about the
949+ strucure of the existing document stored on disk, and the new version of the
950+ document; the document must match the given selector in order for the update to
951+ be accepted.
952+
953+ To use Mango selectors for validation, the design document must have the
954+ ``language`` field set to ``query``. The selector is applied to a JSON structure
955+ containing the following fields:
956+
957+ * ``newDoc``: New version of document that will be stored.
958+ * ``oldDoc``: Previous version of document that is already stored.
959+
960+ For example, to check that all docs contain a ``title`` which is a string, and a
961+ ``year`` which is a number:
962+
963+ .. code-block:: json
964+
965+ {
966+ "language": "query",
967+
968+ "validate_doc_update": {
969+ "newDoc": {
970+ "title": { "$type": "string" },
971+ "year": { "$type": "number" }
972+ }
973+ }
974+ }
975+
976+ All the features of Mango selectors are supported here, so any condition that
977+ can be expressed as a selector can be implemented in this way. Operators like
978+ ``$lt`` and ``$gt`` can be used to restrict values to a given range,
979+ ``$allMatch`` can be used to check all the items in an array match some schema,
980+ and it is even possible to implement conditional checks using logical
981+ combinators.
982+
983+ For example, say we want documents with ``"type": "movie"`` to have a ``title``
984+ and ``year`` as above, and documents with ``"type": "actor"`` to have a ``name``
985+ and a non-empty list of strings under ``movies``. This can be achieved using
986+ this design document:
987+
988+ .. code-block:: json
989+
990+ {
991+ "language": "query",
992+
993+ "validate_doc_update": {
994+ "newDoc": {
995+ "type": { "$in": ["movie", "actor"] },
996+ "$or": [
997+ {
998+ "type": "movie",
999+ "title": { "$type": "string" },
1000+ "year": { "$type": "number" }
1001+ },
1002+ {
1003+ "type": "actor",
1004+ "name": { "$type": "string" },
1005+ "movies": {
1006+ "$type": "array",
1007+ "$not": { "$size": 0 },
1008+ "$allMatch": { "$type": "string" }
1009+ }
1010+ }
1011+ }
1012+ }
1013+ }
1014+ }
0 commit comments