I need to fetch couchdb documents by a bunch of ids. Is there an request / API to do it ?
I don't want to create a view (id, docs) and then do a find by keys.
when the id b-tree already exists
You should use the bulk API documented here.
It could look something like below.
Pass in the keys as part of the body via a POST
Pass in the name of the db (in the example below, it's demodb)
in the url, use the _all_docs for the view
if you want the entire documents returned (and not just the rev), be sure to pass include_docs=true
curl -d '{"keys":["docId1","docId2","docId3"]}' -X POST http://127.0.0.1:5984/demodb/_all_docs?include_docs=true
If you want to fetch a range of documents, you can also use startkey_docid and limit parameters like you would in a view.
What you do is a GET request to a URL like
http://127.0.0.1:5984/demodb/_all_docs?startkey_docid="docId1"&limit=5
Once you have your set of results, you can use the last returned it as the next startkey and run the request again. This has the benefit of skipping view indexing processes (which can be a pain in the ass for large databases).
Documented in the CouchDB API, here.
If you're using the python-couchdb library, you can use:
_, _, response = <your_db>.resource.post_json('_bulk_get', {'docs': [{'id': '<1st_doc_id>'}, {'id': '<2nd_doc_id>'}]})
Your results will be in response['results'].
Related
I have a database and I want to truncate all records, I know it is possible to just add a _deleted key to every document or call db.delete() on CouchDB-python library. I am using the delete of couchdb-python but it does not seem to work when I fetch all the documents and then call .delete on each document excluding design documents.
Here is my code.
docs = get_db().view('_all_docs', include_docs=True)
for i in docs:
if not(i['id'].startswith('_')):
get_db().delete(i)
This is the error. Because the result from _all_docs is returning a id instead _id.
File "C:\Users\User\AppData\Local\Programs\Python\Python36-32\lib\site-packages\couchdb\client.py", line 625, in delete
if doc['_id'] is None:
KeyError: '_id'
My question is how do I fetch all documents that returns _id instead of just the id? Or is there any way around this?
In couchdb-python a view query returns a list of couchdb.client.Row objects, not a list of the docs. You need to pass an attribute doc to that delete, i.e. get_db().delete(i['doc']).
From performance perspective, however, it's better to use bulk api. With couchdb-python it should look something like this:
rows = get_db().view('_all_docs', include_docs=True)
docs = []
for row in rows:
if row['id'].startswith('_'):
continue
doc = row['doc']
doc['_deleted'] = True
docs.append(doc)
get_db().update(docs)
Deleting documents from CouchDB you can create in two step:
create a view (with filtering the documents you want to delete)
use the view to delete all documents using the view
I have written a tool for this.
HI I'm new to cloudant (and couch and asking questions on stackoverflow so I hope I manage to be vaguely clear about what I'm asking ) and I'm trying to do probably the second most basic geo task but am hitting a dead end.
I've got a database of docs which are geojson objects, I've created an index so I can query for intersections etc but it seems the only options I have in the url is the format=legacy (gives me the ids) and the format=geojson and the include_docs parameter - what I'd like to do is give back a particular view of the result set - I'm not interested in the geometry of the object (which is a big lump of data and it's likely that a number of other properties may be in the document that I'd rather filter out)
is there a correct way to do this in a single api call or do I need to fetch the doc ids (legacy format) and then issue a second query to bring back my chosen 'view' for each document id given in the result of format=legacy response
Thanks
Folks, I was wondering what is the best way to model document and/or map functions that allows me "Not Equals" queries.
For example, my documents are:
1. { name : 'George' }
2. { name : 'Carlin' }
I want to trigger a query that returns every documents where name not equals 'John'.
Note: I don't have all possible names before hand. So the parameters in query can be any random text like 'John' in my example.
In short: there is no easy solution.
You have four options:
sending a multi range query
filter the view response with a server-side list function
using a CouchDB plugin
use the mango query language
sending a multi range query
You can request the view with two ranges defined by startkey and endkey. You have to choose the range so, that the key John is not requested.
Unfortunately you have to find the commit request that somewhere exists and compile your CouchDB with it. Its not included in the official source.
filter the view response with a server-side list function
Its not recommended but you can use a list function and ignore the row with the key John in your response. Its like you will do it with a JavaScript array.
using a CouchDB plugin
Create an additional index with e.g. couchdb-lucene. The lucene server has such query capabilities.
use the "mango" query language
Its included in the CouchDB 2.0 developer preview. Not ready for production but will be definitely included in the stable release.
I'm playing with DocumentDB's client side javascript API. I want to be able to query a collection. I'd like to use a collection URL, something like:
"https://mydocumentdb.documents.azure.com:9443/dbs/my_db/colls/my_users"
but there appears to be no API function for me to query a documentdb collection without first having the database "self link" and then in turn getting the collections "self link". The only way to get these self links appears to be to first iterate through all my DB's and then pull the right self link, then iterate through my collections, get the collection, finally, use my self link that I got from the service to query the collection.
Really???
Not exactly.
You're correct in that you have to query for a collection's self-link prior to querying the collection. (I know... this can be quite annoying, and is being looked in to by the DocDB team).
However, there is no need to iterate through all of your DB/collections to retrieve self-links as they are indexed server-side.
It is better to query directly for the particular DB/collection you're looking for, which looks something like: client.queryCollections(database._self, 'SELECT * FROM collections c WHERE c.id="' + collectionId + '"'), where collectionId is an identifier you assign.
How to get Post with Comments Count in single query with CouchDB?
I can use map-reduce to build standalone view [{key: post_id, value: comments_count}] but then I had to hit DB twice - one query to get the post, another to get comments_count.
There's also another way (Rails does this) - count comments manually, on the application server and save it in comment_count attribute of the post. But then we need to update the whole post document every time a new comment added or deleted.
It seems to me that CouchDB is not tuned for such a way, unlike RDBMS when we can update only the comment_count attribute in CouchDB we are forced to update the whole post document.
Maybe there's another way to do it?
Thanks.
The view's return json includes the document count as 'total_rows', so you don't need to compute anything yourself, just emit all the documents you want counted.
{"total_rows":3,"offset":0,"rows":[
{"id":...,"key":...,value:doc1},
{"id":...,"key":...,value:doc2},
{"id":...,"key":...,value:doc3}]
}