Skip to content

CouchDB - Updating a Document

In CouchDB, documents are not modified in place. Instead, updating a document means creating a new revision of it. This process is fundamental to CouchDB’s Multi-Version Concurrency Control (MVCC) model, which prevents data loss in distributed or highly concurrent environments.

Every document in CouchDB has a _id (its unique identifier) and a _rev (its revision number). To update a document, you must provide the _rev of the version you are updating. If the _rev you provide matches the one currently in the database, your update is accepted, and a new revision is created with a new _rev. If it doesn’t match, CouchDB rejects the update with a 409 Conflict error. This mechanism ensures that you don’t accidentally overwrite changes made by another process.

The cURL command-line tool is excellent for testing and direct API interaction. The workflow to update a document has two steps:

Step 1: Get the Current Document to find its _rev

Section titled “Step 1: Get the Current Document to find its _rev”

Let’s assume we have a user profile in our profiles database with the id user123.

# Request
$ curl -X GET http://127.0.0.1:5984/profiles/user123
# Response
{
"_id": "user123",
"_rev": "1-a954784578bca65545a1989467262913",
"name": "Alice",
"email": "alice@example.com",
"status": "active"
}

Take note of the _rev value: 1-a954784578bca65545a1989467262913.

Step 2: Submit the Updated Document with the _rev

Section titled “Step 2: Submit the Updated Document with the _rev”

Now, we’ll update the user’s status to inactive. We must include the entire document body along with the _rev we just fetched.

# Request
$ curl -X PUT http://127.0.0.1:5984/profiles/user123 -d \
'{
"_id": "user123",
"_rev": "1-a954784578bca65545a1989467262913",
"name": "Alice",
"email": "alice@example.com",
"status": "inactive"
}'
# Response
{
"ok": true,
"id": "user123",
"rev": "2-d7b1372551421f5286f7887720c1e879"
}

Success! The response shows "ok": true and provides the new revision number, which starts with 2-. If we wanted to update the document again, we would need to use this new _rev.

Programmatic Updates: Using Node.js and Axios

Section titled “Programmatic Updates: Using Node.js and Axios”

In a real application, you’ll perform these operations programmatically. Here is a complete example using Node.js and the popular axios HTTP client. First, ensure you have axios installed: npm install axios.

const axios = require('axios');
const dbUrl = 'http://127.0.0.1:5984/profiles';
const docId = 'user123';
async function updateUserStatus(newStatus) {
try {
// Step 1: Fetch the latest document to get the current _rev
console.log(`Fetching document: ${docId}`);
const getResponse = await axios.get(`${dbUrl}/${docId}`);
const document = getResponse.data;
console.log(`Current revision is: ${document._rev}`);
// Step 2: Modify the document and prepare the update payload
const updatedDocument = {
...document, // Copy all existing fields
status: newStatus, // Overwrite the status field
updatedAt: new Date().toISOString() // Add a new field
};
// The _rev is already in the document object, so we don't need to add it again.
// Step 3: PUT the updated document back to the database
console.log(`Updating document with status: ${newStatus}`);
const putResponse = await axios.put(`${dbUrl}/${docId}`, updatedDocument);
console.log('Update successful!');
console.log('New revision:', putResponse.data.rev);
return putResponse.data;
} catch (error) {
// Handle potential errors
if (error.response) {
console.error(`Error: ${error.response.status} - ${error.response.data.reason}`);
if (error.response.status === 409) {
console.error('Conflict: The document was updated by another process. Please retry the operation.');
}
} else {
console.error('An unexpected error occurred:', error.message);
}
return null;
}
}
// Run the update function
updateUserStatus('suspended');

Updating Documents using the Fauxton Web UI

Section titled “Updating Documents using the Fauxton Web UI”

Fauxton is the modern, built-in web administration console for CouchDB. It provides a user-friendly way to manage documents. (Access it at http://127.0.0.1:5984/_utils/)

  1. Navigate to your database: From the main Fauxton dashboard, click on the ‘Databases’ icon on the left and then select your database (e.g., profiles) from the list.
  2. Select the document: A list of documents in the database will appear. Click on the _id of the document you wish to update (e.g., user123).
  3. Edit the document: The document’s content will be displayed as editable JSON in a text editor. You can directly modify the values of the fields. For example, change the "status" value from "active" to "inactive".
  4. Save the changes: Click the green ‘Save Document’ button. Fauxton automatically handles fetching the latest _rev and including it in the update request, making the process seamless and safe from conflicts.
  • Handling 409 Conflict: This is not an error; it’s a feature. Your application logic must be prepared to handle it. The correct strategy is to catch the 409, re-fetch the document to get the new _rev, and re-apply your changes before attempting the PUT request again.
  • Bulk Updates: If you need to update many documents at once, do not send one request per document. This is inefficient. Instead, use the _bulk_docs endpoint to send a batch of updated documents in a single HTTP request for significantly better performance.
  • Never Hardcode _rev: The revision of a document is dynamic. Never hardcode a _rev value in your application code. Always fetch it just before you intend to perform an update.