3

I'm new to CouchDb. When I installed it, I thought it would be something like MongoDb, but mongo now seems to be more transparent than couch. At least, in mongo I could insert and get data almost right away, using find(), in couch I do not see such a simple way of doing a query. So, imagine, that I saved a document

{'type':'post','theme':'blabla'}

And now I need to query all posts. How would I do that in Python (using couchdb module)?

1
  • 1
    Queries are done via "Views" in CouchDB, a completely different concept. In the end you do not traverse the data, you traverse the B-Tree created by your View. A explanation from SQL to CouchDB can be found here: guide.couchdb.org/draft/cookbook.html Commented Mar 2, 2015 at 21:38

2 Answers 2

4

First, try creating a view.

function(doc) {
  if(doc.type) {
    emit(doc.type);
  }
}

See here for more information on views: http://guide.couchdb.org/draft/views.html

Next, write some python. I only have experience with the cloudant-python library which would look something like this:

import cloudant

account = cloudant.Account('http://localhost:5984')
db = account.database('yourdb')

view = db.view('theview')
options = {
    'key': 'post',
    'include_docs': True
}
for row in view.iter(params=options):
    # emits only rows with the key 'post'
    # with each row's emitting document

Note: this should also work for CouchDB

Sign up to request clarification or add additional context in comments.

1 Comment

How to create the view programmatically? (I think it's different in python-cloudant than in python-couchdb)...
1

The easiest thing you can use is a Mango Query:

First, let's make the database and save your document (using save, create is deprecated):

import couchdb
s = couchdb.Server()  # this is http://localhost:5984/ by default
db = s.create('posts')
db.save({'type': 'post', 'theme': 'blabla'})

We should have the setup OP described.

Querying with find

for doc in db.find({'selector': {'type': 'post'}}):
    # process your doc
    print(doc)

That's it! Read more about the possibilities here: http://localhost:5984/_utils/docs/api/database/find.html

Note, that the JSON query is passed as a normal Python dict. The selector can have multiple conditions, not only on equality:

db.find({'selector': {'type': 'post', 'theme': {'$regex': '^bla'}})

Don't forget the index

If you were using the API directly, you would get a warning in the result. The query didn't use an index! For larger DBs this would be slow.

Creating the index programmatically was a challenge, but I learned how to do it via source diving (you don't need to do it often - it's a DB administration task, and you can do it with Fauxton UI).

Here's how to access and see indexes:

idx = db.index()

To display:

>>> list(idx)
[{'ddoc': None,
  'name': '_all_docs',
  'type': 'special',
  'def': {'fields': [{'_id': 'asc'}]}}]

And now create a new one, on type:

idx[None, None] = ['type']

(passing None will generate a random Design Document, and a random name for the index (UUIDs)):

>>> list(idx)
[{'ddoc': None,
  'name': '_all_docs',
  'type': 'special',
  'def': {'fields': [{'_id': 'asc'}]}},
 {'ddoc': '_design/3298cb694b9b0e42b2a70030ece92eca87d3552d',
  'name': '3298cb694b9b0e42b2a70030ece92eca87d3552d',
  'type': 'json',
  'def': {'fields': [{'type': 'asc'}]}}]

If you will be filtering on theme, you can add that, too:

idx['ddoc_theme_idx', 'theme_idx'] = [{'theme': 'asc'}]

Which gives:

>>> list(idx)
[{'ddoc': None,
  'name': '_all_docs',
  'type': 'special',
  'def': {'fields': [{'_id': 'asc'}]}},
 {'ddoc': '_design/3298cb694b9b0e42b2a70030ece92eca87d3552d',
  'name': '3298cb694b9b0e42b2a70030ece92eca87d3552d',
  'type': 'json',
  'def': {'fields': [{'type': 'asc'}]}},
 {'ddoc': '_design/ddoc_theme_idx',
  'name': 'theme_idx',
  'type': 'json',
  'def': {'fields': [{'theme': 'asc'}]}}]

The index can be on multiple fields - just add more fields on the list, e.g.:

idx[None, None] = ['type', 'theme']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.