Skip to content

Table of contents

Mango

Create an index for some documents

The body should contain a index JSON field containing a fields which is an ordered array of fields to index.

Request

POST /data/:doctype/_index HTTP/1.1
POST /data/io.cozy.events/_index HTTP/1.1
Content-Type: application/json
{
    "index": {
        "fields": ["calendar", "date"]
    }
}

Response OK

HTTP/1.1 200 OK
Date: Mon, 27 Sept 2016 12:28:53 GMT
Content-Length: ...
Content-Type: application/json
{
    "result": "created",
    "id": "_design/a5f4711fc9448864a13c81dc71e660b524d7410c",
    "name": "a5f4711fc9448864a13c81dc71e660b524d7410c"
}

Details

  • if the doctype does not exist, the database is created.
  • if the index already exists, a {result: "exists"} is returned, but the response code is still 200
  • design doc & name can be provided in request. This is not recommended, let couchdb handle naming and deduplication.
{
  "name": "by-calendar-and-date",
  "ddoc": "_design/some-ddoc-name",
  "index": { "fields": ... }
}

Possible errors

  • 401 unauthorized (no authentication has been provided)
  • 403 forbidden (the authentication does not provide permissions for this action)
  • 500 internal server error

Find documents

Find allows to find documents using a mango selector. You can read more about mango selectors here

Request

POST /data/:doctype/_find HTTP/1.1
POST /data/io.cozy.events/_find HTTP/1.1
Content-Type: application/json
{
    "selector": {
        "calendar": "perso",
        "date": { "$gt": "20161001T00:00:00" }
    },
    "limit": 2,
    "sort": ["calendar", "date"],
    "fields": ["_id", "_type", "_date"],
    "execution_stats": true,
    "use_index": "_design/a5f4711fc9448864a13c81dc71e660b524d7410c"
}

Response OK

HTTP/1.1 200 OK
Date: Mon, 27 Sept 2016 12:28:53 GMT
Content-Length: ...
Content-Type: application/json
{
    "docs": [
        {
            "_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
            "_type": "io.cozy.events",
            "date": "20161023T160000Z"
        },
        {
            "_id": "6494e0ac-dfcb-472e84a9cbee",
            "_type": "io.cozy.events",
            "date": "20161013T160000Z"
        }
    ],
    "execution_stats": {
        "total_docs_examined": 10,
        "results_returned": 2,
        "execution_time_ms": 8.833
    },
    "bookmark": "g1AAAAB2eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJB",
    "limit": 2,
    "next": true
}

Details

  • If an index does not exist for the selector, an error 400 is returned
  • The sort field must contains all fields used in selector
  • The sort field must match an existing index
  • It is possible to sort in reverse direction sort:[{"calendar":"desc"}, {"date": "desc"}] but all fields must be sorted in same direction.
  • use_index is optional but recommended.
  • execution_stats is false by default. It gives execution information about the query. See here for more details.

Pagination cookbook

Pagination of mango query should be handled by the client. The stack will limit query results to a maximum of 100 documents. This limit can be raised up to 1000 documents per page with the limit parameter, but not further.

The limit applied to a query is visible in the HTTP response.

If the limit cause some docs to not be returned, the response will have a next=true top level values. Then, the returned bookmark value can be used in the next query to get the missing docs. It is also possible to use skip, to paginate, although this is not recommended for performances. For more details, see the CouchDB documentation.

{
    "limit": 100,
    "next": true,
    "docs": ["... first hundred docs ..."],
    "bookmark": "g1AAAAB2eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGKQYpVqaJRoZm1paWFiapFkamhknGpilJiampZkYJRmC9HHA9OUAdTASpS0rCwAlah76"
}

If the number of docs is lower than the limit, next will be false.

{
    "limit": 100,
    "next": false,
    "docs": ["... less than a hundred docs ..."]
}

Example:

Index on io.cozy.events with fields ["calendar", "date"]

Try to get all events for a month:

"selector": {
  "calendar": "my-calendar",
  "date": { "$gt": "20161001", "$lt": "20161030" }
}

If there is less than 100 events, the response next field will be false and there is nothing more to do. If there is more than 100 events for this month, we have a next=true in the response.

To keep iterating, we can use the bookmark field we received in the next request.

"selector": {
  "calendar": "my-calendar",
  "date": { "$gte": "20161001", "$lt": "20161030" }
},
"bookmark": "g1AAAAB2eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGKQYpVqaJRoZm1paWFiapFkamhknGpilJiampZkYJRmC9HHA9OUAdTASpS0rCwAlah76"