couchdb primary key workaround - couchdb

I am looking for a workaround for primary key feature in couchdb. I am saving doc in json format to couchdb externally. Is there any simple way to check if value of a particular field exists?

If you try to save a document that already exists, it will be rejected unless the revision is set to match the existing revision.
Alternately, you can just try to fetch the document, either with GET or HEAD, to check if it exists. See the relevant documentation.

You could perform a mango query previous to the document creation but it will not warranty that another process create a document between the check and the creation.
This post discusses about the same issue:
How to check for duplication before creating a new document in CouchDB/Cloudant?

Related

CouchDB check if a document exists in a validation function

I would like to see if a document exists in the database that has the name field "name" set to "a name" before allowing a new document to be added to the database.
I this possible in CouchDB using update handlers (inside design documents)?
Seems you are looking for a unique constraint in CouchDB. The only unique constraint supported by CouchDB is based on the document ID.
You should include your "name" attribute value into the document ID if you would like to have the document unicity based on it.
Validate document update functions defined in desing documents can only use the data of the document being created/updated/deleted, it can no use data from other documents in the database.
Yo can find a similar question here.
This is not widely known, but _update endpoint allowed to return a doc with _id prop different from requested. It means, in your case, you need to have an unique document say _id:"doc-name", which will serve as a constraint.
Then you call smth like POST _design/whatever/_update/saveDependentDoc/doc-name, providing new doc with different _id as a request body.
Your _update function will effectively receive two docs as an input (or null and newDoc if constraint doc is missing). The function then decides what should it do: return received doc to persist it, or return nothing.
The solution isn’t a full answer to your question, however it might be helpful in some cases.
This trick only works for updating existing docs if you know revision, for sure.

How to get last created document in couchdb?

How can I get last created document in couchdb? Maybe some how I can use _changes feature of couchdb? But documentation says, that I only can get list of document, ordered by first created document, ant there is no way to change order.
So how can I get last created document?
You can get the changes feed in descending order as it's also a view.
GET /dbname/_changes?descending=true
You can use limit= as well, so;
GET /dbname/_changes?descending=true&limit=1
will give the latest update.
Your only surefire way to get the last created document is to include a timestamp (created_at or something) with your document. From there, you just need a simple view to output all the docs by their creation date.
I was going to suggest using the last_seq information from the database, but the sequence number changes with every single write, and replication also complicates the matter further.

How to do partial update of a document

I need a guidance on how can I update a field in CouchDB. I tried curl via console it works fine but programatically. I don't understand how to update a particular field say 'name'. Here is the snippet of updating a document in CouchDB which works fine and returns me the updated revision id.
HttpPut httpPutRequest = new HttpPut(hostUrl +"/"+ docId);
StringEntity body = new StringEntity(jsonDoc.toString());
httpPutRequest.setEntity(body);
httpPutRequest.setHeader("Accept", "application/json");
httpPutRequest.setHeader("Content-type", "application/json");
Partial updates are not supported by CouchDB. In other words, to update a field in the document, you must update the field in your local JSON document and push that document to CouchDB as a whole.
You can accomplish this by still issuing an HTTP PUT, ensuring the appropriate _rev is included in your document.
More details are available in the wiki.
It is possible to support partial updates by writing your own update function.
To be clear, it not actually a truly partial update. It still update the whole target document into new revision. But the update was done directly on the database itself. And so you could specified update partially on client side instead of retrieving and sending the whole document

I want absolute atomicity on a single couchdb instance (insert, fail if already existing)

I've come to really love the couchdb style of organizing and updating data, but there are a few situations where I really need to be able to create an entry and determine if an equivalent entry is already in existence before returning to the user. The only situation that this is absolutely necessary for my application is user registration. I'm fine with having all user registration writes go to a particular, designated couchdb instance known as the "registration-instance".
I want to hash the user_id into some _id to use. Then execute a put with this _id, but fail if the _id is already inserted. I need to return to the user that the user name is already reserved, and I cannot detect the conflict later and resolve it at that point, because the user would be under the impression that they had reserved the user name.
I don't see why couchdb couldn't provide some way to do this, under the assumption that you designate that inserts for a particular "type" of document always are routed to a particular instance.
If you send a single CouchDB server a PUT request for a new user document you should get the behavior you want already.
If the document does not exist then it will create the new document.
If the document does exist then it is guaranteed to return a 409 conflict error. This is due to the fact that you did not supply a _rev property because you aren't trying to update the pre-existing document.
Only when the _id and _rev properties match will CouchDB update the existing document.
You might also want to read up on document update handlers:
http://wiki.apache.org/couchdb/Document_Update_Handlers
You might use an update handler to hash the user_id and dynamically assign the appropriate _id. You can also customize what kind of error response couch sends with an update handler.
Good luck!

Delete document with an empty ID

I have a CouchDB database in production. One of the documents has been edited (in Futon by an other developer).
And it's lost it's ID (don't ask me how he did it).
So now the document's id is an empty string, which makes it impossible to edit or delete via Futon.
Is there a way I could hack into CouchDB to delete that document anyway ?
I couldn't delete the document. But the database itself could be deleted.
And I couldn't reproduce the bug in locale. The other developer says he just removed the _id param and saved. I don't know what happened in CouchDB when he did it. But when I do so, it only recreates a new document (as we'd expect it to do).
So I've been using couch_docs to retrieve the datas locally.
As the id is empty, couch_docs doesn't imports it. So you don't even need to delete it manually.
Then I reimport all the records in an other database. I change the references to the database name in my config and everything works fine.
Destroying the database is not a problem even though there's an empty id.
Technically, a document ID is immutable so actually changing the _id field is not directly possible. Perhaps another document was created as a copy of the first?
A bug in CouchDB 1.1.0 allowed update functions to create empty string IDs.
A similar question asks about this and I gave a walkthrough of deleting empty ids there.
I haven't tried it but LoveSeat is supposed to be able to open and edit couchedb files...
This can be caused (and fixed!) by some error checking CouchDB was missing for _update handlers, as explained in How do you delete a couchdb document with an empty "" document id?

Resources