12

How to fetch multiple documents from CouchDB, in particular with couchdb-python?

dnolen
  • 18,496
  • 4
  • 62
  • 71

3 Answers3

22

Easiest way is to pass a include_docs=True arg to Database.view. Each row of the results will include the doc. e.g.

>>> db = couchdb.Database('http://localhost:5984/test')
>>> rows = db.view('_all_docs', keys=['docid1', 'docid2', 'missing'], include_docs=True)
>>> docs = [row.doc for row in rows]
>>> docs
[<Document 'docid1'@'...' {}>, <Document 'docid2'@'...' {}>, None]

Note that a row's doc will be None if the document does not exist.

This works with any view - just provide a list of keys suitable to the view.

Matt Goodall
  • 1,682
  • 10
  • 7
  • 2
    True, but docs don't make any sense after a reduce anyway. A reduce combines items from multiple documents (the map's emitted (key, value) pairs) into a single result. Therefore, a reduce row is made up of many documents and the idea of a a reduce row's doc is meaningless. Of course, you can skip a view's reduce by passing a reduce=False keyword arg and that can be combined with include_docs=True just fine. But that's not a reduce any more; only a map. – Matt Goodall Nov 27 '09 at 11:58
4

This is the right way:

import couchdb

server = couchdb.Server("http://localhost:5984")
db = server["dbname"]
results = db.view("_all_docs", keys=["key1", "key2"])
Anand Chitipothu
  • 4,167
  • 4
  • 24
  • 26
  • This is true only if you don't what fine grained control over the results. My method allows you ask for keys from _all_docs that don't exist, and you'll get back a empty placeholder for the non-existant keys. If you attempt this with your method you'll get an exception when iterating over the results. Why would want to do something like this? Fast manual joins. You have x documents and you want to join in data from other documents. – dnolen Oct 29 '09 at 16:37
  • @dnolen: Actually, that's not true... there's an error in the `__repr__` code for a row result, that is true, but you can just do `[ row for row in db.view('_all_docs', keys=["key1", "key2"]).rows if 'value' in row ]` to get rows that exist. – Walt W Oct 04 '10 at 19:02
-7
import couchdb
import simplejson as json

resource = couchdb.client.Resource(None, 'http://localhost:5984/dbname/_all_docs')
params = {"include_docs":True}
content = json.dumps({"keys":[idstring1, idstring2, ...]})
headers = {"Content-Type":"application/json"}
resource.post(headers=headers, content=content, **params)
resource.post(headers=headers, content=content, **params)[1]['rows']
dnolen
  • 18,496
  • 4
  • 62
  • 71
  • 3
    -1: This answer was posted at the same time the question was asked, and was accepted over a more API-conforming answer that was posted before this solution was marked as accepted. – Walt W Oct 04 '10 at 19:04