How design documents work
IBM® Cloudant® for IBM Cloud® reads specific fields and values of design documents as functions. Design documents are used to build indexes and validate updates.
Each design document defines either partitioned or global indexes, which are controlled by the options.partitioned
field. A partitioned index allows only queries over a single data partition in a partitioned
database. A global index allows querying over all data within a database, at a cost of latency and throughput over a partitioned index.
Creating or updating a design document
- Method
PUT /$DATABASE/_design/$DDOC
- Request
- JSON of the design document information.
- Response
- JSON status.
- Roles permitted
_admin
To create a design document, upload it to the specified database.
In these examples,
$VARIABLES
might refer to standard or design documents. To distinguish between them, standard documents have an _id
indicated by $DOCUMENT_ID
, while design documents have an _id
indicated
by $DDOC
.
A design document's ID never includes a partition key regardless of the database's partitioning type. The partition key isn't included because the indexes that are included within a design document apply to all partitions in a partitioned database.
If a design document is updated, IBM Cloudant deletes the indexes from the previous version, and re-creates the index from scratch. If you need to change a design document for a larger database, have a look at the Design document management guide.
A design document's structure includes the following parts:
_id
-
Design document ID. This ID is always prefixed
_design
and never includes a partition key, regardless of database partitioning type. _rev
-
Design document revision.
- Options
-
Contains options for this design document.
Partitioned (optional, boolean) : Determines whether this design document describes partitioned or global indexes. For more information, see [The `options.partitioned` field](#the-options-partitioned-field).
- Views (optional)
-
An object that describes MapReduce views.
`Viewname` : (One for each view) - View Definition. Map : Map Function for the view.
- Reduce (optional)
-
Reduce Function for the view.
- Indexes (optional)
-
An object that describes search indexes.
- Index name
- (One for each index) - Index definition.
- Analyzer
- Object that describes the analyzer to be used or an object with the following fields:
- Name
-
Name of the analyzer. Valid values are
standard
,email
,keyword
,simple
,whitespace
,classic
, andperfield
. - Stopwords (optional)
-
An array of stop words. Stop words are words that must not be indexed. If this array is specified, it overrides the default list of stop words. The default list of stop words depends on the analyzer. The standard analyzer includes the following list of stop words:
a
,an
,and
,are
,as
,at
,be
,but
,by
,for
,if
,in
,into
,is
,it
,no
,not
,of
,on
,or
,such
,that
,the
,their
,then
,there
,these
,they
,this
,to
,was
,will
, andwith
. - Default (for the per field analyzer)
-
Default language to use if no language is specified for the field.
- Fields (for the per field analyzer)
- An object that specifies which language to use to analyze each field of the index. Field names in the object correspond to field names in the index, that is, the first parameter of the index function. The values of the fields are the
languages to be used, for example
english
. - Index
- Function that handles the indexing.
- Filters (optional, disallowed when
partitioned
istrue
) -
Filter functions.
- Function name (one for each function)
- Function definition.
- Validate_doc_update (optional, disallowed when
partitioned
istrue
) -
Update validation function.
The options.partitioned
field
This field sets whether the created index is a partitioned or global index.
This field includes the following values:
Value | Description | Notes |
---|---|---|
true |
Create the index as partitioned. | Can be used only in a partitioned database. |
false |
Create the index as global. | Can be used in any database. |
The default follows the partitioned
setting for the database:
Database is partitioned? | Default partitioned value |
Allowed values |
---|---|---|
Yes | true |
true , false |
No | false |
false |
Copying a design document
You can copy the latest version of a design document to a new document by specifying the base document and target document. The copy is requested by using the COPY
request method.
COPY
is a nonstandard HTTP command.
The following example requests that IBM Cloudant copy the design document allusers
to the new design document copyOfAllusers
, and produces a response that includes the ID and revision of the new document.
Copying a design document doesn't automatically reconstruct the view indexes. Like other views, these views are re-created the first time that you access the new view.
See the following example command to copy a design document by using HTTP:
COPY $SERVICE_URL/$DATABASE/_design/$DDOC HTTP/1.1
Content-Type: application/json
Destination: _design/$COPY_OF_DDOC
See the following example command to copy a design document:
The IBM Cloudant SDKs currently do not support the HTTP COPY method.
curl "$SERVICE_URL/users/_design/allusers" \
-X COPY \
-H "Content-Type: application/json" \
-H "Destination: _design/copyOfAllusers"
See the following example response to the copy request:
{
"ok": true,
"id": "_design/copyOfAllusers",
"rev": "1-9c65296036141e575d32ba9c034dd3ee"
}
The structure of the copy command
- Method
COPY /$DATABASE/_design/$DDOC
- Request
- None.
- Response
- JSON describing the new document and revision.
- Roles permitted
_design
Query Arguments
- Argument
-
rev
- Description
- Revision to copy from.
- Optional
- Yes.
- Type
- String.
HTTP Headers
- Header
-
Destination
- Description
- Destination document (and optional revision)
- Optional
- No.
The source design document is specified on the request line, while the Destination
HTTP Header of the request specifies the target document.
Copying from a specific revision
To copy from a specific version, add the rev
argument to the query string.
The new design document is created by using the specified revision of the source document.
See the following example command to copy a specific revision of the design document by using HTTP:
COPY $SERVICE_URL/$DATABASE/_design/$DDOC?rev=$REV HTTP/1.1
Content-Type: application/json
Destination: _design/$COPY_OF_DDOC
See the following example command to copy a specific revision of the design document by using the command line:
curl "$SERVICE_URL/users/_design/allusers?rev=1-e23b9e942c19e9fb10ff1fde2e50e0f5" \
-X COPY \
-H "Content-Type: application/json" \
-H "Destination: _design/copyOfAllusers"
Copying to an existing design document
To overwrite or copy to an existing document, specify the current revision string for the target document by using the rev
parameter to the Destination
HTTP Header string.
See the following example command to overwrite an existing copy of the design document by using HTTP:
COPY $SERVICE_URL/$DATABASE/_design/$DDOC
Content-Type: application/json
Destination: _design/$COPY_OF_DDOC?rev=$REV
See the following example command to overwrite an existing copy of the design document by using the command line:
curl "$SERVICE_URL/users/_design/allusers" \
-X COPY \
-H "Content-Type: application/json" \
-H "Destination: _design/copyOfAllusers?rev=1-9c65296036141e575d32ba9c034dd3ee"
The return value is the ID and new revision of the copied document.
See the following example response to overwrite an existing copy of the design document:
{
"id" : "_design/copyOfAllusers",
"rev" : "2-55b6a1b251902a2c249b667dab1c6692"
}
Deleting a design document
You can delete an existing design document. Deleting a design document also deletes all of the associated view indexes, and recovers the corresponding space on disk for the indexes in question.
To delete a design document successfully, you must specify the current revision of the design document by using the rev
query argument.
See the following example command to delete a design document by using HTTP:
DELETE $SERVICE_URL/$DATABASE/_design/$DDOC?rev=$REV HTTP/1.1
See the following examples to delete a design document:
curl "$SERVICE_URL/users/_design/allusers?rev=2-21314508552eceb0e3012429d04575da" -X DELETE
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.delete_design_document(
db='users',
ddoc='allusers',
rev='2-21314508552eceb0e3012429d04575da'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DeleteDesignDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
Cloudant service = Cloudant.newInstance();
DeleteDesignDocumentOptions designDocumentOptions =
new DeleteDesignDocumentOptions.Builder()
.db("users")
.ddoc("allusers")
.rev("2-21314508552eceb0e3012429d04575da")
.build();
DocumentResult response =
service.deleteDesignDocument(designDocumentOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.deleteDesignDocument({
db: 'users',
ddoc: 'allusers',
rev: '2-21314508552eceb0e3012429d04575da'
}).then(response => {
console.log(response.result);
});
deleteDesignDocumentOptions := service.NewDeleteDesignDocumentOptions(
"users",
"allusers",
)
deleteDesignDocumentOptions.SetRev("2-21314508552eceb0e3012429d04575da")
documentResult, response, err := service.DeleteDesignDocument(deleteDesignDocumentOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
The previous Go example requires the following import block:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
See the following example response that includes the deleted document ID and revision:
{
"id": "_design/allusers",
"ok": true,
"rev": "3-7a05370bff53186cb5d403f861aca154"
}
The structure of the delete command
- Method
DELETE /db/_design/$DDOC
- Request
- None.
- Response
- JSON of deleted design document.
- Roles permitted
_design
Query Arguments
- Argument
-
rev
- Description
- Current revision of the document for validation.
- Optional
- Yes, if
If-Match
header exists. - Type
- String.
HTTP Headers
- Header
-
If-Match
- Description
- Current revision of the document for validation.
- Optional
- Yes, if
rev
query argument exists.
Views
An important use of design documents is for creating views. For more information about creating views, see Views (MapReduce).
Indexes
All queries operate on pre-defined indexes that are defined in design documents. These indexes are defined in the following list:
For example, to create a design document that is used for searching, you must ensure that two conditions are true:
-
You defined the document as a design document when you started the
_id
with_design/
. -
You created a search index within the document where you updated the document with the appropriate field or created a new document that includes the search index.
As soon as the search index design document exists and the index is built, you can make queries by using it.
General notes on functions in design documents
Functions in design documents are run on multiple nodes for each document, and might be run several times. To avoid inconsistencies, they need to be idempotent, meaning they need to behave identically when run multiple times or on different nodes. In particular, you must not use functions that generate random numbers or return the current time.
Filter functions
Design documents with options.partitioned
set to true
can't contain a filters
field.
Filter functions are design documents that filter the changes feed. They work by applying tests to each of the objects included in the changes feed.
If any of the function tests fail, the object is "removed" or "filtered" from the feed. If the function returns a true
result when applied to a change, the change remains in the feed. In other words, filter functions
"remove" or "ignore" changes that you don't want to monitor.
Filter functions can also be used to modify a replication task.
Filter functions require two arguments: doc
and req
.
The doc
argument represents the document that is tested for filtering.
The req
argument includes more information about the request. With this argument, you can create filter functions that are more dynamic because they're based on multiple factors such as query parameters or the user context.
For example, you could control aspects of the filter function tests by using dynamic values that are provided as part of the HTTP request. However, in many filter function use cases, only the doc
parameter is used.
See the following example design document that includes a filter function:
{
"_id":"_design/example_design_doc",
"filters": {
"example_filter": "function (doc, req) { ... }"
}
}
See the following example of a filter function:
function(doc, req){
// we need only `mail` documents
if (doc.type != 'mail'){
return false;
}
// we're interested only in `new` ones
if (doc.status != 'new'){
return false;
}
return true; // passed!
}
Changes feed filter functions
To apply a filter function to the changes feed, include the filter
parameter in the _changes
query, providing the name of the filter to use.
See the following example of a filter function that is applied to a _changes
query by using HTTP:
POST $SERVICE_URL/$DATABASE/_changes?filter=$DDOC/$FILTER_FUNCTION HTTP/1.1
See the following examples of a filter function applied to a _changes
query:
curl -X POST "$SERVICE_URL/orders/_changes?filter=example_design_doc/example_filter" -H "Content-Type: application/json" -d '{}'
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
db='orders',
filter='example_design_doc/example_filter'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
.db("orders")
.filter("example_design_doc/example_filter")
.build();
ChangesResult response =
service.postChanges(changesOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.postChanges({
db: 'orders',
filter: 'example_design_doc/example_filter'
}).then(response => {
console.log(response.result);
});
postChangesOptions := service.NewPostChangesOptions(
"$DATABASE",
)
postChangesOptions.SetFilter("example_design_doc/example_filter")
changesResult, response, err := service.PostChanges(postChangesOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(changesResult, "", " ")
fmt.Println(string(b))
The previous Go example requires the following import block:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
Filter function req
argument
The req
argument gives you access to aspects of the HTTP request by using the query
property.
See the following example of supplying a req
argument by using HTTP:
GET $SERVICE_URL/$DATABASE/_changes?filter=$DDOC/$FILTER_FUNCTION&status=new HTTP/1.1
See the following example of supplying a req
argument:
The IBM Cloudant SDKs currently do not support status
option for _changes
request.
curl "$SERVICE_URL/$DATABASE/_changes?filter=$DDOC/$FILTER_FUNCTION&status=new"
See the following example filter by using a supplied req
argument:
function(doc, req){
// we need only `mail` documents
if (doc.type != 'mail'){
return false;
}
// we're interested only in `new` ones
if (doc.status != req.query.status){
return false;
}
return true; // passed!
}
Predefined filter functions
A number of predefined filter functions are available:
_design
- Accepts only changes to design documents.
_doc_ids
- Accepts only changes for documents whose ID is specified in the
doc_ids
parameter or supplied JSON document. _selector
- Accepts only changes for documents that match a specified selector that is defined by using the same selector syntax as described in the Request section, which is
used for
_find
. _view
- With this function, you can use an existing map function as the filter.
The _design
filter
The _design
filter accepts changes only for design documents within the requested database.
The filter doesn't require any arguments.
Changes are listed for all the design documents within the database.
See the following example application of the _design
filter by using HTTP:
POST /$DATABASE/_changes?filter=_design HTTP/1.1
See the following example applications of the _design
filter:
curl -X POST "$SERVICE_URL/orders/_changes?filter=_design" -H "Content-Type: application/json" -d '{}'
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
db='orders',
filter='_design'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
.db("orders")
.filter("_design")
.build();
ChangesResult response =
service.postChanges(changesOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.postChanges({
db: 'orders',
filter: '_design'
}).then(response => {
console.log(response.result);
});
postChangesOptions := service.NewPostChangesOptions(
"$DATABASE",
)
postChangesOptions.SetFilter("_design")
changesResult, response, err := service.PostChanges(postChangesOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(changesResult, "", " ")
fmt.Println(string(b))
The previous Go example requires the following import block:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
See the following example response (abbreviated) after you apply the _design
filter:
{
...
"results":[
{
"changes":[
{
"rev":"10-304...4b2"
}
],
"id":"_design/ingredients",
"seq":"8-g1A...gEo"
},
{
"changes":[
{
"rev":"123-6f7...817"
}
],
"deleted":true,
"id":"_design/cookbook",
"seq":"9-g1A...4BL"
},
...
]
}
The _doc_ids
filter
The _doc-ids
filter accepts only changes for documents with specified IDs. The IDs are specified in a doc_ids
parameter, or within a JSON document supplied as part of the original request.
See the following example application of the _doc_ids
filter by using HTTP:
POST $SERVICE_URL/$DATABASE/_changes?filter=_doc_ids HTTP/1.1
See the following example applications of the _doc_ids
filter:
curl -X POST "$SERVICE_URL/orders/_changes?filter=_doc_ids" -H "Content-Type: application/json" -d '{"doc_ids": ["ExampleID"]}'
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
db='orders',
filter='_doc_ids',
doc_ids=['ExampleID']
).get_result()
print(response)
import java.util.Arrays;
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
.db("orders")
.filter("_doc_ids")
.docIds(Arrays.asList("ExampleID"))
.build();
ChangesResult response =
service.postChanges(changesOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.postChanges({
db: 'orders',
filter: '_doc_ids',
docIds: ['ExampleID']
}).then(response => {
console.log(response.result);
});
postChangesOptions := service.NewPostChangesOptions(
"$DATABASE",
)
postChangesOptions.SetFilter("_doc_ids")
postChangesOptions.SetDocIds([]string{"ExampleID"})
changesResult, response, err := service.PostChanges(postChangesOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(changesResult, "", " ")
fmt.Println(string(b))
The previous Go example requires the following import block:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
See the following example JSON document that lists document IDs to match during filtering:
{
"doc_ids": [
"ExampleID"
]
}
See the following example response (abbreviated) after you filter by _docs_ids
:
{
"last_seq":"5-g1A...o5i",
"pending":0,
"results":[
{
"changes":[
{
"rev":"13-bcb...29e"
}
],
"id":"ExampleID",
"seq":"5-g1A...HaA"
}
]
}
The _selector
filter
The _selector
filter accepts only changes for documents that match a specified selector, which is defined by using the same selector syntax that is used for
_find
.
For more examples that show use of this filter, see the information on selector syntax.
See the following example application of the _selector
filter by using HTTP:
POST $SERVICE_URL/$DATABASE/_changes?filter=_selector HTTP/1.1
See the following example applications of the _selector
filter:
curl -X POST "$SERVICE_URL/orders/_changes?filter=_selector" -H "Content-Type: application/json" -d '{"selector": {"_id": { "$regex": "^_design/"}}}'
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
db='orders',
filter='_selector',
selector={'_id': { '$regex': '^_design/'}}
).get_result()
print(response)
import java.util.HashMap;
import java.util.Map;
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
Map<String, Object> selector = new HashMap<String, Object>();
selector.put("_id", new HashMap<>().put("$regex", "^_design/"));
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
.db("orders")
.filter("_selector")
.selector(selector)
.build();
ChangesResult response =
service.postChanges(changesOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.postChanges({
db: 'animaldb',
filter: '_selector',
selector: {"_id": { "$regex": "^_design/"}},
}).then(response => {
console.log(response.result);
});
postChangesOptions := service.NewPostChangesOptions(
"$DATABASE",
)
postChangesOptions.SetFilter("_selector")
postChangesOptions.SetSelector(map[string]interface{}{
"_id": map[string]string{ "$regex": "^_design/"}})
changesResult, response, err := service.PostChanges(postChangesOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(changesResult, "", " ")
fmt.Println(string(b))
The previous Go example requires the following import block:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
See the following example JSON document that includes the selector expression to use during filtering:
{
"selector":{
"_id":{
"$regex":"^_design/"
}
}
}
See the following example response (abbreviated) after you filter by using a selector:
{
"last_seq":"11-g1A...OaA",
"pending":0,
"results":[
{
"changes":[
{
"rev":"10-304...4b2"
}
],
"id":"_design/ingredients",
"seq":"8-g1A...gEo"
},
{
"changes":[
{
"rev":"123-6f7...817"
}
],
"deleted":true,
"id":"_design/cookbook",
"seq":"9-g1A...4BL"
},
{
"changes":[
{
"rev":"6-5b8...8f3"
}
],
"deleted":true,
"id":"_design/meta",
"seq":"11-g1A...Hbg"
}
]
}
The _view
filter
Using the _view
filter, you can use an existing map function as the filter.
The map function might emit output as the result of processing a specific document. When this situation occurs, the filter considers the document that is allowed and includes it in the list of documents that you changed.
See the following example application of the _view
filter by using HTTP:
POST $SERVICE_URL/$DATABASE/_changes?filter=_view&view=$DDOC/$VIEW_NAME HTTP/1.1
See the following example applications of the _view
filter:
curl -X POST "$SERVICE_URL/animaldb/_changes?filter=_view&view=views101/latin_name" -H "Content-Type: application/json" -d '{}'
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
db='animaldb',
filter='_view',
view='views101/latin_name'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
.db("animaldb")
.filter("_vew")
.view("views101/latin_name")
.build();
ChangesResult response =
service.postChanges(changesOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.postChanges({
db: 'animaldb',
filter: '_view',
view: 'views101/latin_name'
}).then(response => {
console.log(response.result);
});
postChangesOptions := service.NewPostChangesOptions(
"animaldb",
)
postChangesOptions.SetFilter("_view")
postChangesOptions.SetView("views101/latin_name")
changesResult, _, err := service.PostChanges(postChangesOptions)
if err != nil {
fmt.Println(err)
}
b, _ := json.MarshalIndent(changesResult, "", " ")
fmt.Println(string(b))
See the following example response (abbreviated) after you filter by using a map function:
{
"last_seq": "5-g1A...o5i",
"results": [
{
"changes": [
{
"rev": "13-bcb...29e"
}
],
"id": "ExampleID",
"seq": "5-g1A...HaA"
}
]
}
Update validators
Design documents with options.partitioned
set to true
can't contain a validate_doc_update
field.
Update validators determine whether a document must be written to disk when insertions and updates are attempted. They don't require a query because they implicitly run during this process. If a change is rejected, the update validator responds with a custom error.
Update validators require four arguments:
Argument | Purpose |
---|---|
newDoc |
The version of the document passed in the request. |
oldDoc |
The version of the document currently in the database, or null if none exists. |
secObj |
The security object for the database. |
userCtx |
Context regarding the currently authenticated user, such as name and roles . |
Update validators don't apply when a design document is updated by an admin user. This practice ensures that admins can never accidentally lock themselves out.
See the following example design document with an update validator:
{
"_id": "_design/validator_example",
"validate_doc_update": "function(newDoc, oldDoc, userCtx, secObj) { ... }"
}
See the following example of an update validator:
function(newDoc, oldDoc, userCtx, secObj) {
if (newDoc.address === undefined) {
throw({forbidden: 'Document must have an address.'});
}
}
See the following example response from an update validator:
{
"error": "forbidden",
"reason": "Document must have an address."
}
Retrieving information about a design document
Two endpoints provide you with more information about design documents: _info
and _search_info
.
The _info
endpoint
The _info
endpoint returns information about a specific design document, including the view index, view index size, and status of the design document and associated view index information.
- Method
GET /db/_design/$DDOC/_info
- Request
- None
- Response
- JSON that contains the design document information.
- Roles permitted
_reader
See the following example of retrieving information about the recipesdd
design document from within the recipes
database by using HTTP:
GET /recipes/_design/recipesdd/_info HTTP/1.1
See the following examples of retrieving information about the recipesdd
design document from within the recipes
database:
curl "$SERVICE_URL/recipes/_design/recipesdd/_info"
getDesignDocumentInformationOptions := service.NewGetDesignDocumentInformationOptions(
"recipes",
"recipesdd",
)
designDocumentInformation, response, err := service.GetDesignDocumentInformation(getDesignDocumentInformationOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(designDocumentInformation, "", " ")
fmt.Println(string(b))
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_design_document_information(
db='recipes',
ddoc='recipesdd'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DesignDocumentInformation;
import com.ibm.cloud.cloudant.v1.model.GetDesignDocumentInformationOptions;
Cloudant service = Cloudant.newInstance();
GetDesignDocumentInformationOptions informationOptions =
new GetDesignDocumentInformationOptions.Builder()
.db("recipes")
.ddoc("recipesdd")
.build();
DesignDocumentInformation response =
service.getDesignDocumentInformation(informationOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getDesignDocumentInformation({
db: 'recipes',
ddoc: 'recipesdd'
}).then(response => {
console.log(response.result);
});
The JSON response includes the following individual fields:
name
-
Name or ID of design document.
view_index
-
View Index
compact_running
- Indicates whether a compaction routine runs on the view.
disk_size
- Size in bytes of the view as stored on disk.
language
- Language that is used for defining views.
purge_seq
- The purge sequence that was processed.
signature
- MD5 signature of the views for the design document.
update_seq
- The update sequence of the corresponding database that was indexed.
updater_running
- Indicates whether the view is being updated.
waiting_clients
- Number of clients that are waiting on views from this design document.
waiting_commit
- Indicates whether the underlying database has outstanding commits that need to process.
See the following example response in JSON format:
{
"name" : "recipesdd",
"view_index": {
"compact_running": false,
"updater_running": false,
"language": "javascript",
"purge_seq": 10,
"waiting_commit": false,
"waiting_clients": 0,
"signature": "fc65594ee76087a3b8c726caf5b40687",
"update_seq": 375031,
"disk_size": 16491
}
}
The _search_info
endpoint
The _search_info
endpoint returns information about a specified search that is defined within a specific design document.
- Method
GET /db/_design/$DDOC/_search_info/yourSearch
- Request
- None
- Response
- JSON that contains information about the specified search.
- Roles permitted*
_reader
See the following example of getting information about the description
search, which is defined within the app
design document that is stored in the foundbite
database, by using HTTP:
GET /foundbite/_design/app/_search_info/description HTTP/1.1
See the following examples of getting information about the description
search index, which is defined within the app
design document that is stored in the foundbite
database:
curl "$SERVICE_URL/foundbite/_design/app/_search_info/description"
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_search_info(
db='foundbite',
ddoc='app',
index='description'
).get_result()
print(response)
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.GetSearchInfoOptions;
import com.ibm.cloud.cloudant.v1.model.SearchInfoResult;
Cloudant service = Cloudant.newInstance();
GetSearchInfoOptions infoOptions =
new GetSearchInfoOptions.Builder()
.db("foundbite")
.ddoc("app")
.index("description")
.build();
SearchInfoResult response =
service.getSearchInfo(infoOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getSearchInfo({
db: 'foundbite',
ddoc: 'app',
index: 'description'
}).then(response => {
console.log(response.result);
});
getSearchInfoOptions := service.NewGetSearchInfoOptions(
"foundbite",
"app",
"description",
)
searchInfoResult, response, err := service.GetSearchInfo(getSearchInfoOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(searchInfoResult, "", " ")
fmt.Println(string(b))
The JSON structure includes the following individual fields:
name
-
Name or ID of the Search within the design document.
search_index
-
The Search Index
pending_seq
- The sequence number of changes in the database that reached the Lucene index, both in memory and on disk.
doc_del_count
- Number of deleted documents in the index.
doc_count
- Number of documents in the index.
disk_size
- The size of the index on disk, in bytes.
committed_seq
- The sequence number of changes in the database that were committed to the Lucene index on disk.
See the following example response in JSON format:
{
"name":"_design/app/description",
"search_index":{
"pending_seq":63,
"doc_del_count":3,
"doc_count":10,
"disk_size":9244,
"committed_seq":63
}
}