Get couchdb views to process design-docs as well as other docs - couchdb

I am trying to get a view in couchdb to include design docs. I have done it in the past, but can not get it to work today.
In a past couchapp there is a file called options.json that contains the text:
{
"include_design": "true"
}
This results in the design doc containing
"options": {
"include_design": "true"
},
I added this to the new project, but still the design doc is not processed by my views. Is there something that I missed?
CouchDB 1.7.1

According to this documentation, include_design option is a boolean.
I double-checked CouchDB to see how it saves Boolean values by adding a document to a sample database with a Boolean value for one of the keys:
$ cat doc--0000
{"time":"2011", "address":"CT", "include":true}
$ curl -k -X PUT https://admin:**#192.168.1.106:6984/sample/doc--0000 -d #doc--0000
{"ok":true,"id":"doc--0000","rev":"1-e269c17275e2d21ba9100cd65b304d70"}
$ curl -k -X GET https://admin:**#192.168.1.106:6984/sample/doc--0000
{"_id":"doc--0000","_rev":"1-e269c17275e2d21ba9100cd65b304d70","time":"2011","address":"CT","include":true}
The double-check confirms that the Boolean values are saved as true NOT "true". I'm not sure, maybe that's the cause of the issue.

#user3405291 is correct the problem is with the string "true" instead of boolean true. CouchDB doesn't save this. Your view is run on the server as a javascript script so you should write it like you write javascript anywhere.

Related

Using a script to conditionally update a document in Elasticsearch

I have a use case in which concurrent update requests make hit my Elasticsearch cluster. In order to make sure that a stale event (one that is made irrelevant by a newer request) does not update a document after a newer event has already reached the cluster, I would like to pass a script with my update requests to compare a field to determine if the incoming request is relevant or not. The request would look like this:
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '
{
"script": " IF ctx._source.user_update_time > my_new_time THEN do not update ELSE proceed with update",
"params": {
"my_new_time": "2014-09-01T17:36:17.517""
},
"doc": {
"name": "new_name"
},
"doc_as_upsert": true
}'
Is the pseudo code I wrote in the "script" field possible in Elasticsearch ? If so, I would love some help with the syntax (groovy, python or javascript).
Any alternative approach suggestions would be greatly appreciated too.
Elasticsearch has built-in optimistic concurrency control (+ here and here).
The way it works is that the Update API allows you two use the version parameter in order to control whether the update should proceed or not.
So taking your above example, the first index/update operation would create a document with version: 1. Then take the case where you have two concurrent requests. Both components A and B will send an updated document, they initially have both retrieved the document with version: 1 and will specify that version in their request (see version=1 in the query string below). Elasticsearch will update the document if and only if the provided version is the same as the current one
Component A and B both send this, but A's request is the first to make it:
curl -XPOST 'localhost:9200/test/type1/1/_update?version=1' -d '{
"doc": {
"name": "new_name"
},
"doc_as_upsert": true
}'
At this point the version of the document will be 2 and B's request will end up with HTTP 409 Conflict, because B assumed the document was still at version 1, even though the version increased in the meantime due to A's request.
B can definitely retrieve the document with the new version (i.e. 2) and try its update again, but this time with ?version=2in the URL. If it's the first one to reach ES, the update will succeed.
I think the script should be like this:
"script": "if(ctx._source.user_update_time > my_new_time) ctx._source.user_update_time=my_new_time;"
or
"script": "ctx._source.user_update_time > my_new_time ? ctx.op=\"none\" : ctx._source.user_update_time=my_new_time"

Couch ignores filters

Following this guide I create a design document with one view in it:
"views":{
"user":{
"map":"function(doc){emit(doc.id,doc)}"
}
}
If I then make a curl request like so:
curl .../_view/user
I get a result set, that looks like this:
{"total_rows":5,"offset":0,"rows":[{... value:{"_id":"...","login":"admin"}},...]}
If, however, I want to filter results by login field (now following this guide), like so:
curl ... /_view/user?login="test_login"
or ... /_view/user?login=test_login
I still get the very same result-set. I wonder what I'm doing wrong.
EDIT
I change the view a little bit, so that login attribute is now a key:
"map":"function(doc){emit(doc.login,doc)}"
However, even in this case filtering stil does not work. Whether I do:
/_view/user?login="root"
or
/_view/user?login="blahblahblah"
Taking all this into account, I guess, my final question should be: Does anybody in the world use CouchDB, if it is not working at all? I played around with dozens of databases, and all of them work as I expect it. CouchDB is a major exception.

validate_on_update prevents deletion of a specified document

I have a simple validate_on_update function:
if (!newDoc.type) {
throw({forbidden: "All documents must have a type specified"});
}
If I do
curl -X DELETE $HOST/$DB/$DOC?rev=$REV
I get back
{"error":"forbidden","reason":"All documents must have a type specified"}
This happens even if I do
rev=$REV&type=type
Or if I do
-d'{"type":"type"}'
with curl
How can I bypass validation for deletion of documents?
CouchDB internals only know reads and updates. An update can eb the creation of the doc, an edit of a doc, or the deletion of the doc. Update funs can’t be circumvented for any type. To solve this, use if(!newDoc.type || doc._deleted) {

I am using river-couchdb with ElasticSearch and would like to reset its last_seq to 0. Anybody know if that's possible?

I am using this a plugin with elasticSearch called river-couchdb to create a full text index of my couchdb. It uses the couchdb _changes api to listen for documents. I assume it is keeping track of the last seq from the _changes api.
Sometimes we rebuild our CouchDB and set our last-seq back to 0. Only way I've found to reset the river-couchdb seq is to delete both its index and the river itself and recreate it. Is there a better way?
As far as I remember, you have a _seq document in your _river index for your river.
This document has a _last_seq entry.
If you want to restart from scratch, I think you can simply delete this document:
curl -XDELETE localhost:9200/_river/yourrivername/_seq
Does it help?
From couchdb-river manual:
starting-at-a-specific-sequence
curl -XDELETE localhost:9200/_river/yourrivername/_seq
curl -XPUT 'localhost:9200/_river/yourrivername/_seq' -d '
{
"couchdb": {
"last_seq": "100"
}
}'
Elasticsearch cant update last_seq without deleting old document

Can I retrieve all revisions of a deleted document?

I know I can retrieve all revisions of an "available" document, but can I retrieve the last "available" version of a deleted document? I do not know the revision id prior to the delete. This is the command I am currently running...it returns {"error":"not_found","reason":"deleted"}.
curl -X GET http://localhost:5984/test_database/a213ccad?revs_info=true
I've got this problem, trying to recover deleted document, here is my solution:
0) until you run a compaction, get deleted history, e.g.:
curl http://example.iriscouch.com/test/_changes
1) you'll see deleted documents with $id and $rev, put empty document as new version, e.g.:
curl -X PUT http://example.iriscouch.com/test/$id?rev=$rev -H "Content-Type: application/json" -d {}
2) now you can get all revisions info, e.g:
curl http://example.iriscouch.com/test/$id?revs_info=true
See also Retrieve just deleted document
Besides _changes, another good way to do this is to use keys with _all_docs:
GET $MYDB/_all_docs?keys=["foo"] ->
{
"offset": 0,
"rows": [
{
"id": "foo",
"key": "foo",
"value": {
"deleted": true,
"rev": "2-eec205a9d413992850a6e32678485900"
}
}
],
"total_rows": 0
}
Note that it has to be keys; key will not work, because only keys returns info for deleted docs.
You can get the last revision of a deleted document, however first you must first determine its revision id. To do that, you can query the _changes feed and scan for the document's deletion record — this will contain the last revision and you can then fetch it using docid?rev=N-XXXXX.
I remember some mailinglist discussion of making this easier (as doing a full scan of the changes feed is obviously not ideal for routine usage), but I'm not sure anything came of it.
I've hit this several times recently, so for anyone else wandering by ...
This question typically results from a programming model that needs to know which document was deleted. Since user keys such as 'type' don't survive deletion and _id is best assigned by couch, it would often be nice to peak under the covers and see something about the doc that was deleted. An alternative is to have a process that sets deleted:True (no underscore) for documents, and to adjust any listener filters, etc., to look for deleted:True. One of the processes can then actually delete the document. This means that any process triggering on the document doesn't need to track an _id for eventual deletion.

Resources