Couchdb

From wikinotes

Couchdb is a Document database designed for very large scale.

  • data stores as JSON objects
  • views are pre-made/indexed queries written in javascript
  • queries are made via HTTP, filters on views applied with URL params.

Documentation

Tutorials

view intro http://guide.couchdb.org/draft/cookbook.html
couchdb queries http://sitr.us/2009/06/30/database-queries-the-couchdb-way.html
couchdb best practices https://github.com/eHealthAfrica/couchdb-best-practices

Locations

/etc/couchdb/local.ini

Ports

5984

Install

Archlinux

sudo pacman -S couchdb
sudo systemctl enable couchdb.service
sudo systemctl start  couchdb.service

Usage

cdbcli

An interactive shell for couchdb.
See cdbcli.

HTTP

GET      # retrieve a file/query
POST     # update a file
PUT      # create a file
DELETE   # delete a file
curl http://127.0.0.1:5984                                    # test access to database

curl -X GET     http://127.0.0.1:5984/test_database/document  # get a file

curl -X PUT     http://127.0.0.1:5984/test_database           # create a database

curl -X DELETE  http://127.0.0.1:5984/test_database           # delete a database/document

curl -X POST    http://127.0.0.1:5984/test_database/document \ 
                -H 'Content-Type: application/json'          \
                -d @/path/to/file.json                        # update a file

special things

curl -X GET http://127.0.0.1:5984/_all_dbs                  # get list of all databases
curl -X GET http://127.0.0.1:5984/test_database/_all_docs   # get list of all documents/revisions from a database
curl -X GET http://127.0.0.1:5984/_uuids                    # request a uuid from the server


cdbcli

cdbcli lets you treat your couchdb installation like it is a filesystem... kind of... I find that the lack of vi-mode, and aliases makes me struggle more than just simply using curl. but it did help me quickly understand couchdb's concepts, and that is really worth something.


cdbcli -h 127.0.0.1 

mkdir test_database
cd    test_database
touch first_doc
vim   first_doc
touch _design/some_related_views


Concepts

Documents

couchdb stores it's information in documents. These are just ordinary json files, the only special part about them is that they require 2x fields (that will be created automatically if not present):

  • _id
  • _rev

When POSTing new json files, you do not need to worry about these fields. ex:

{
   //"_id": "your_filename",
   //"_rev": "a long uuid",
   "name":     "will",
   "age":      30,
   "shoesize": 13
}
# create database and document
curl -X PUT  http://127.0.0.1:5984/database
curl -X PUT  http://127.0.0.1:5984/database/document

# add above json file
curl -X POST http://127.0.0.1:5984/database/document -t 'Content-Type application/json' -d @file.json



Views

summary

This is where couch is much different from other databases. Instead of using SQL, and running queries on the fly, couchdb prefers that you create queries in advance (in javascript). The return is in the form of a key (which the results will be sorted by), and a JSON payload (nested dict, key, list, ...).

The returned documents, and their fields are determined primarily by the map function. This set of results can be further isolated using a filter function.

curl -X GET https://localhost:8601/blog/_design/docs/_view/by_date?startkey="2010/01/01 00:00:00"&endkey="2010/02/00 00:00:00"
  • designs can comprise of several views
  • each view builds a document
  • view-documents can be filtered by the values of their queried keys


designs

Design documents define views.

{
  "_id"  : "my_database/_design/group_of_queries", // path to design-doc
  "_rev" : "1-8fc484a77d9d4c348ef9566b669af239",
  "views": {
     "all_docs"            : {
        "map" : "function(doc) {                      emit( doc.id, doc.shoesize );   }"
     },
     "docs_with_shoesizes" : {
           "map" : "function(doc) {   if (doc.shoesize){ emit( doc.id, doc.shoesize ); } }"
      }
  }
}

views

Views are written inside design documents. When queried, they have a subpath _view/my_view_name. Views are written in javascript. Views are composed of a map function, and an optional reduce function. They are both written in javascript.

my_database/_design/my_design_doc/_view/my_view_name    ## path to query a specific view from.

map

The map function determines the results that get returned. Every map function returns 2x results (but they can both comprise of other datatypes if you need more info).

  • The first returned item is the key. The results are sorted by this alphabetically.
  • The second returned item is any data you would like passed along.
  • All results are returned with their _id value.
function(doc) {
    emit( doc.date, [ doc.name, doc.desc ] );
}
## curl -X GET http://localhost:8601/db/_design/mydesign/_view/myview
{
    "total_rows": 3,
    "offset": 0,
    "rows": [
        {
            "key": "2009/01/15 15:52:20",
            "id": "hello-world",
            "value": ["example", "a simple example"]
        },

        {
            "key": "2009/01/30 18:04:11",
            "id": "biking",
            "value": ["sport", "a sport performed on 2x wheels"]
        },

        {
            "key": "2009/02/17 21:13:39",
            "id": "bought-a-cat",
            "value": ["activity", "obtained a pet"]
        }

    ]
}

reduce

The reduce function operates on the results returned by map.

Query Parameters

If you want to retrieve a maximum-of N entries, or you want to restrict your entries to a specific date-range you can add additional information to the URL used in the query.

The query parameters are passed after the _view is named. Start your parameters with a ?. Afterwards, they are separated by &.

key

# Only return results whose key matches this string exactly
# searches view 'last' for all entries whose key == 'pittman'
curl -X GET http://localhost:5984/testdb/_design/by_name/_view/last?key=pittman

startkey & endkey

# Only return results between startkey/endkey (alphabetically).
/blog/_design/docs/_view/by_date?startkey="2010/01/01 00:00:00"&endkey="2010/02/00 00:00:00"

descending=1

# Order is inversed. (Order is normally alphabetical by key).
/blog/_design/docs/_view/by_date?descending=1

limit=1

# get a single document (the last alphabetical)
curl -X GET http:/localhost:5984/testdb/_all_docs?descending=1&limit=1

Query Examples


couchdb example: basics
couchdb example: list as key

Designs Quirks

This is a list of things you should probably be aware of before getting too deeply involved in setting up your datastructures:

  • Nothing is ever deleted. If you create a key, then delete it, it will remain. Existing keys can be updated.
  • all users are 'root' in couchdb until configured otherwise.
  • databases are created at the root. There is no other hierarchy (_design/<design_name> is actually treated as a document name)

Best Practices

Management

Users

Backup

Replication