str3.me

blog about

title

CouchDB with Mango

30 Dec 2016

Mango is a acronym for MongoDB inspired query language interface for Apache CouchDB. Cloudant choses the MongoDB Filter Query Language because it is well known in the NoSQL Community. The JSON style query language from MongoDB fit's great with CouchDB together.

If you want to follow the tutorial to step by step just clone the repro from github with

git clone https://github.com/kstrempel/mango-first-steps.git

followed by

cd mango-first-steps

to enter the exercise directory.

Prepare the database

To create the tutorial database we run.

PUT http://127.0.0.1:5984/books

Now we add some data to our books databse.

POST http://127.0.0.1:5984/books/_bulk_docs
Content-Type: application/json
Authorization: Basic :auth
{
    "docs": [
        {
            "_id": "1",
            "name" : "Snow Crash",
            "author" : "Neal Stephenson",
            "year" : 1991
        },
        {
            "_id": "2",
            "name" : "Cryptonomicon",
            "author" : "Neal Stephenson",
            "year" : 1999
        },
        {
            "_id": "3",
            "name" : "Flatland",
            "author" : "Edwin A. Abbot",
            "year" : 1884
        },
        {
            "_id": "4",
            "name" : "Neuromancer",
            "author" : "William Gibson",
            "year" : 1984
        },
        {
            "_id": "5",
            "name" : "The Periphal",
            "author" : "William Gibson",
            "year" : 2014
        },
        {
            "_id": "6",
            "name" : "CouchDB: The Definitive Guide",
            "author" : ["J. Chris Anderson", "Jan Lehnardt", "Noah Slater"],
            "year" : 2010
        },
        {
            "_id": "7",
            "name" : "Crypto",
            "author" : "Steven Levy",
            "year" : 2001
        }
    ]
}

Now we have a database with 7 entries. To see them all you can against with alldocs

GET http://127.0.0.1:5984/books/_all_docs/?include_docs=true

A nice list with some of my favorite books.

Prepare the drum-roll

Let's use Mango to filter all books from the current century.

POST http://127.0.0.1:5984/books/_find
Content-Type: application/json
 {
  "selector": {
    "year": {
      "$gte": 2000
    }
  }
}

The opposite can be done with a simple operator change.

POST http://127.0.0.1:5984/books/_find
Content-Type: application/json
{
  "selector": {
    "year": {
      "$lte": 2000
    }
  }
}

We can filter by author.

POST http://127.0.0.1:5984/books/_find
Content-Type: application/json
{
  "selector": {
    "author": {
      "$eq": "Neal Stephenson"
    }
  }
}

Or get all books starting with 'C'

POST http://127.0.0.1:5984/books/_find
Content-Type: application/json
{
  "selector": {
    "name": {
      "$regex": "^C"
    }
  }
}

Yes you see it right. There is a regex filter in CouchDB now.

Creating a Index

For every query you see a warning in the result.

{
  "docs": [
    {
      "year": 1991,
      "author": "Neal Stephenson",
      "name": "Snow Crash",
      "_rev": "1-f43ca5556a31a21684a5fb39ca34d93a",
      "_id": "1"
    }
  ],
  "warning": "no matching index found, create an index to optimize query time"
}

To avoid these warnings and improve the speed of the mango queries you have to create a index for your queries.

POST http://127.0.0.1:5984/books/_index
Authorization: Basic :auth
Content-Type: application/json
{
  "index": {
    "fields": [
      {
        "year": "desc"
      }
    ]
  }
}

Now there should be no warnings for queries against the year.

Mango operators

Currently Mango supports the following equality operators.

Combinations

Like in MongoDB you can create queries with combinations.

Doing and 'and' combinated query to search for all authors starting with 'C' and wrote a book after 2000.

{
  "selector": {
    "name": {
      "$regex": "^C"
    },
    "year": {
      "$gt" : 2000
    }
  }
}

For a 'or' combination we need to embed the single queries in the 'or' operator.

{
  "selector": 
    {"$or": [
      {"name": {"$regex": "^C"}},
      {"year": {"$gt" : 2000}}
    ]}
}

This is a list for all current combination operators.

More features of Mango

Additionally to the new query language mango supports inserts, updates and delete operators. But this should be part of another blog post.

comments powered by Disqus
Kai Strempel