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.
- "$lt" - less than
- "$lte" - less than equal
- "$eq" - equal
- "$ne" - not equal
- "$gte" - greater than equal
- "$gt" - greater than
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.
- "$and" - array argument
- "$or" - array argument
- "$not" - single argument
- "$nor" - array argument
- "$all" - array argument (special operator for array values)
- "$elemMatch" - single argument (special operator for array values)
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.