I'm using python-couchdb library to listen to the changes in database using continuous feed. I want to apply a filter which gives me only those documents that have a key read
equal to true
.
With normal HTTP GET request, I get the desired results. But I'm not able to figure out how to do this via couchdb-python
library. Here is a custom filter that I've written:
def read_true_filter():
return """function(doc, req) {
if(doc.read === true) {
return true;
}
return false;
}
"""
Here is how I'm trying to listen to the changes:
db_changes = db.changes(
feed='continuous',
include_docs=True,
heartbeat=1000,
since=last_seq_id,
filter=read_true_filter
)
But this gives me the error:
Traceback (most recent call last):
File "../src/couch_pull_pipeline.py", line 87, in <module>
db_changes = db.changes(
File "/Users/sanyam/venv/lib/python3.5/site-packages/couchdb/client.py", line 1027, in _changes
_, _, data = self.resource.get('_changes', **opts)
File "/Users/sanyam/venv/lib/python3.5/site-packages/couchdb/http.py", line 546, in get
return self._request('GET', path, headers=headers, **params)
File "/Users/sanyam/venv/lib/python3.5/site-packages/couchdb/http.py", line 581, in _request
credentials=self.credentials)
File "/Users/sanyam/venv/lib/python3.5/site-packages/couchdb/http.py", line 421, in request
raise ServerError((status, error))
couchdb.http.ServerError: (400, ('bad_request', 'filter parameter must be of the form `designname/filtername`'))
Adding designname
in the request is simple, but I couldn't find equivalent of doing this using couchdb client.
Is it possible using the python library or I should use simple HTTP requests or a better idea is to have the filter on the couchdb server itself? (As per what I've read so far, it is not a good idea to have that filter in couchdb due to performance reasons.)
Can someone provide me pointer on what I'm doing wrong / how to go about it?
I figured this out. I made a design document in the database where I wanted to filter the contents like:
{
"_id": "_design/read_validator",
"_rev": "1-bd5fb337899a0eaf485b2112b439cc30",
"filters": {
"read_only_true": "function(doc, req) {if(doc.read === true) {return true;}return false;}"
}
}
Here read_validator
is the design document which includes the filter to return docs
which has read
attribute set to true
. In the couchdb python client, while getting continuous feed, I gave the filter resource path as a string design_document_name/filter_name
where design_document
is the name of design document created in the db (in this case it is read_validator
) and filter_name
is the name of the filter (in this case it is read_only_true
). So, the connection is like this:
db_changes = db.changes(
feed='continuous',
include_docs=True,
heartbeat=1000,
since=last_seq_id,
filter="read_validator/read_only_true"
)
Here db_changes
would be a continuous feed generator through which all the documents could be fetched through iterating, that have read
key equal to true
.