Cascade Delete
This example illustrates how to leverage the Eventing Service to perform a cascade delete operation.
Need for Cascade Delete Operation
Couchbase is a NoSQL data platform and therefore does not provide referential integrity. When a user gets deleted, the data platform should provide a reliable method to delete all dependent transactions and documents of the user.
Developing your Handler Code
Create a JavaScript Function that contains an OnDelete handler. The handler listens to data-changes within a specified source bucket, the users bucket. When a user within the source bucket gets deleted, the handler executes a routine to remove the deleted user.
In this example, the handler executes the routine when a delete operation is performed. The handler then uses a N1QL query to fetch all associated documents/transactions of this user. All the fetched documents are removed from the cluster. The handler then records the delete operation in a Function-specific application log file.
A sample handler code for cascade delete is provided.
function OnUpdate(doc, meta) { log('OnUpdate document:', meta.id); } function OnDelete(meta) { log('Document Deleted:', meta.id); if(meta.id < 10) { try { var this_user_id = meta.id; delete from `transactions` where user_id = TONUMBER($this_user_id); log('Deleted Orphaned Transactions for User:', this_user_id); } catch(e) { log('Exception:', e) } } }
Prerequisites
Before you begin, you’ll need to ensure that two buckets, metadata and users buckets, are created. See Creating Buckets.
Procedure
Proceed as follows:
-
From the Couchbase Web Console > Eventing page, click ADD FUNCTION, to add a new Function.
-
In the ADD FUNCTION dialog, for individual Function elements, provide the below information:
-
For the Source Bucket drop-down, select the Users bucket option that was created for this purpose.
-
For the Metadata Bucket drop-down, select the metadata bucket option that was created for this purpose.
-
Enter delete_orphaned_txns as the name of the Function you are creating in the Function Name text-box.
-
Enter Delete Orphaned Transactions from the `transactions’ bucket when user_id is less than 10 in the Description text-box.
-
For the Settings option, use the default values.
-
For the Bindings option, specify users as the name of the bucket and specify src_user as its associated value.
-
-
In the ADD FUNCTION dialog, click Next: Add Code. The delete_orphaned_txns dialog appears. The delete_orphaned_txns dialog initially contains a placeholder code block. You will substitute your actual delete_orphaned_txns code in this block.
-
Copy the sample Function handler code, and paste it in the placeholder code block of the delete_orphaned_txns screen:
-
After pasting, the screen appears as displayed below:
-
To return to the Eventing screen, click Eventing. The Function delete_orphaned_txns is listed as a defined Function.
-
Click Deploy.
-
In the Confirm Deploy Function dialog, from the Feed boundary drop-down, select Everything and click Deploy Function.
From this point, the defined Function is executed on all existing documents and on subsequent mutations. -
Navigate to the Couchbase Web Console > Query page. Before deleting a user, a snapshot of Query Resultfrom the users bucket is displayed for reference:
-
The Query Results display users with user_ids from 1 to 10.
-
Navigate to the Couchbase Web Console > Buckets page. Delete two users from the Users bucket:
-
Select User4 from the list and click the delete icon.
-
Select User10 from the list and click the delete icon.
-
-
From the Query Editor, execute an N1QL query to check that all related records for the deleted users are removed from the cluster.
SELECT user_id, COUNT(1) FROM `Users` GROUP BY user_id ORDER BY user_id ASC;
-
In the Query Results pane notice that user_ids, user_id4 and user_id 10 are removed as part of the cascade user delete operation.
To summarize, since Eventing Service is a homegrown offering, we uses N1QL queries in the Function handler code. The transpiler in Couchbase Server converted the N1QL query to a code that the JavaScript engine understands, and thereby made the cascade delete operation look easy.