How to fetch multiple documents from CouchDB, in particular with couchdb-python?
A:
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
2009-10-28 20:52:43
-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
2010-10-04 19:04:15
+2
A:
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
2009-10-29 10:32:03
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
2009-10-29 16:37:13
@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
2010-10-04 19:02:35
+2
A:
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
2009-11-26 13:01:38
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
2009-11-27 11:58:17