A newer version of this documentation is available.

View Latest

Examples: Using the Eventing Service

This page contains examples of how to use the Eventing Service, using the Couchbase Web Console.

Example 1

Goal: A document contains attributes whose form makes them difficult to search on. Therefore, on the document’s creation or modification, a new attribute should be created to accompany each original attribute; this new attribute being instantiated with a value that directly corresponds to that of its associated, original attribute; but takes a different form, thereby becoming more supportive of search. Original attributes are subsequently retrievable based on successful searches performed on new attributes.

Implementation: Create a JavaScript function that contains an OnUpdate handler. The handler listens for data-changes within a specified, source bucket. When any document within the bucket is created or mutated, the handler executes a user-defined routine. In this example, if the created or mutated document contains two specifically named fields containing IP addresses (these respectively corresponding to the beginning and end of an address-range), the handler-routine converts each IP address to an integer. A new document is created in a specified, target bucket: this new document is identical to the old, except that it has two additional fields, which contain integers that correspond to the IP addresses. The original document, in the source bucket, is not changed.

Preparations

This example requires the creation of three buckets: metadata, target and source buckets.

Proceed as follows:

  1. Create target and metadata buckets. To create a bucket, refer to Create a Bucket. The target bucket contains documents that will be created by the Function. Don’t add any documents explicitly to this bucket.

  2. Follow Step 1. and create a source bucket. In the Source bucket screen:

    1. Click Add Document.

    2. In the Add Document window, specify the name SampleDocument as the New*Document ID*

    3. Click Save.

    4. In the Edit Document dialog, paste the following within the edit panel.

      {

      "country": "AD",

      "ip_end": "5.62.60.9",

      "ip_start": "5.62.60.1"

      }

    5. Click Save. This step concludes all required preparations.

Procedure

Proceed as follows:

  1. From the Couchbase Web Console > Eventing page, click ADD FUNCTION, to add a new Function.

  2. In the ADD FUNCTION dialog, for individual Function elements provide the below information:

    • For the Source Bucket drop-down, select the source option that was created for this purpose.

    • For the Metadata Bucket drop-down, select the metadata option that was created for this purpose.

    • Enter enrich_ip_nums as the name of the Function you are creating in the Function*Name* text-box.

    • Enter Enrich a document, converts IP Strings to Integers that are stored in new attributes, in the Description text-box.

    • For the Settings option, use the default values.

    • For the Bindings option, specify target as the name of the bucket, and specify tgt as the associated value.

  3. After providing all the required information in the ADD FUNCTION dialog, click Next: Add Code. The enrich_ip_nums dialog appears. The enrich_ip_nums dialog initially contains a placeholder code block. You will substitute your actual enrich_ip_nums code in this block.

    addfunctions ex1
  4. Copy the following Function, and paste it in the placeholder code block of the enrich_ip_nums dialog:

     function OnUpdate(doc, meta) {
      log('document', doc);
      doc["ip_num_start"] = get_numip_first_3_octets(doc["ip_start"]);
      doc["ip_num_end"]   = get_numip_first_3_octets(doc["ip_end"]);
      tgt[meta.id]=doc;
    }
    
    function get_numip_first_3_octets(ip)
    {
      var return_val = 0;
      if (ip)
      {
        var parts = ip.split('.');
    
        //IP Number = A x (256*256*256) + B x (256*256) + C x 256 + D
        return_val = (parts[0]*(256*256*256)) + (parts[1]*(256*256)) + (parts[2]*256) + parseInt(parts[3]);
        return return_val;
      }
    }

    After pasting, the screen appears as displayed below:

    enrich ip nums

    The OnUpdate routine specifies that when a change occurs to data within the bucket, the routine get_numip_first_3_octets is run on each document that contains ip_start and ip_end. A new document is created whose data and metadata are based on those of the document on which get_numip_first_3_octets is run; but with the addition of ip_num_start and ip_num_end data-fields, which contain the numeric values returned by get_numip_first_3_octets. The get_numip_first_3_octets routine splits the IP address, converts each fragment to a numeral, and adds the numerals together, to form a single value; which it returns.

  5. Click Save.

  6. To return to the Eventing screen, click Eventing and click on the newly created Function name. The Function enrich_ip_nums is listed as a defined Function.

    deploy enrich ip nums
  7. Click Deploy.

  8. From the Confirm Deploy Function dialog, click Deploy Function. From this point, the defined Function is executed on all existing documents and on subsequent mutations.

  9. To check results of the deployed Function, click the Documents tab.

  10. Select target bucket from the Bucket drop-down.As this shows, a version of SampleDocument has been added to the target bucket. It contains all the attributes of the original document, with the addition of ip_num_start and ip_num_end; which contain the numeric values that correspond to ip_start and ip_end, respectively. Additional documents added to the source bucket, which share the ip_start and ip_end attributes, will be similarly handled by the defined Function: creating such a document, and changing any attribute in such a document both cause the Function’s execution.

Example 2

Goal: This example illustrates how to leverage Eventing Service in the Banking and Financial domain. When a credit card transaction exceeds the user’s available credit limit, to indicate a high-risk transaction, an alert can be generated.

This example requires you to create four buckets: *flagged_transactions, users, metadata*and *transactions*buckets. For steps on how to create buckets, see Create Bucket.

Implementation: Create a JavaScript Function that contains an OnUpdate handler. The handler listens to data-changes within a specified, transactions source bucket. When a document within the source bucket is created or mutated, the handler executes a user-defined routine. In this example, if the created or mutated document contains a high-risk transaction, a new document gets created in a specified, flagged_transactions bucket.

Proceed as follows:

  1. From the Couchbase Web Console > Eventing page, click ADD FUNCTION,to add a new Function. The ADD FUNCTION dialog appears.

  2. In the ADD FUNCTION dialog, for individual Function elements provide the below information:

    • For the Source Bucket drop-down, select transactions that was created for this purpose.

    • For the Metadata Bucket drop-down, select metadata that was created for this purpose.

    • Enter high_risks_transactions as the name of the Function you are creating in the Function*Name* text-box.

    • Enter Functions that computes risky transaction and flags them, in the Description text-box.

    • For the Settings option, use the default values.

    • For the Bindings option, add two bindings. For the first binding specify users as the name of the bucket, and specify user as the associated value. For the second binding, specify flagged_transactions as the name of the bucket, and specify high_risk as the associated value.

  3. After providing all the required information in the ADD FUNCTION dialog, click Next: Add Code. The high_risks_transactions dialog appears.

    The high_risks_transactions dialog initially contains a placeholder code block. You will substitute your actual high_risks_transactions code in this block.

    add functions code exp2
  4. Copy the following Function, and paste it in the placeholder code block of the high_risks_transactions dialog:

    function OnUpdate(doc, meta) {
        try
        {
            //log('txn id:', meta.id, '; user_id:', doc.user_id , ', doc.amount:', doc.amount);
            var this_user = getUser(doc.user_id);
            if (this_user)
            {
                if(this_user['creditlimit'] < doc.amount)
                {
                    log('Txn['+String(meta.id)+']*****High Risk Transaction as Txn Amount:'+ String(doc.amount)+' exceeds Credit Limit:',this_user['creditlimit']);
                    doc["comments"] = "High Risk Transaction as Txn Amount exceeds Credit Limit " +String(this_user['creditlimit']);
                    doc["reason_code"] = "X-CREDIT";
                    high_risk[meta.id] = doc;
                    return;
                }
                else
                {
                    if(doc.txn_currency != this_user['currency'])
                    {
                        log('Txn['+ String(meta.id) +']*****High Risk Transaction - Currency Mismatch:'+ this_user['currency']);
                        doc["comments"] = "High Risk Transaction - Currency Mismatch:" + this_user['currency'];
                        doc["reason_code"] = "XE-MISMATCH";
                        high_risk[meta.id] = doc;
                        return;
                    }
                }
                //log('Acceptable Transaction:',doc.amount, ' for Credit Limit:', this_user['creditlimit']);
            }
            else
            {
                log('Txn['+ String(meta.id) + "] User Does not Exist:" + String(doc.user_id) );
            }
         }
        catch (e)
        {
            log('Error OnUpdate :', String(meta.id), e);
        }
    }
    
    function OnDelete(meta) {
        log('Document OnDelete:', meta.id);
    }
    
    function getUser(userId)
    {
        try
        {
            if(userId != null)
            {
                return user[userId];
            }
        }
        catch (e)
        {
            log('Error getUser :', userId,'; Exception:', e);
        }
        return null;
    }

    After pasting, the screen appears as displayed below:

    high risks transactions handler code

    The OnUpdate handler is triggered for every transaction. The handler checks if the transaction amount is less than the user’s available credit limit. When this condition is breached, then this transaction is flagged as a high-risk transaction. The Function high_risks_transactions then moves this transaction to a different bucket, flagged_transactions bucket. When the transaction is moved to a new bucket, the handler enriches the document with predefined comments and also provides a reason code*.* In the last part, the handler performs a currency validation step. If the transaction currency is other than the preconfigured home currency of the user, then the handler flags the transactions and moves it to a different bucket.

  5. Click Save.

  6. To return to the Eventing screen, click Eventing.

    high risks transactions handler deploy

    The Function high_risks_transactionsis listed as a defined Function. Currently, it is listed as Undeployed and Paused.

  7. Click Deploy.

  8. From the Confirm Deploy Function dialog, click Deploy Function. This deploys the Function and displays the main Eventing screen. From this point, the defined Function is executed on all existing documents and on subsequent mutations.

  9. To check results of the deployed Function, after a sufficient time elapse, from the Couchbase Web Console > Eventing page, click Buckets.

  10. Click flagged_transactions bucket. All documents available in this bucket are transactions that are flagged as high-risk transactions.

    buckets

    This indicates that transactions which were flagged as high risk gets moved to the flagged_transactions bucket.

  11. From the Couchbase Web Console > Query page, execute the below N1QL query:

    SELECT reason_code, COUNT(1), num_txns, SUM(amount) amount
    FROM `flagged_transactions`
    GROUP BY reason_code;
    N1QL Query

Example 3

Goal: This example illustrates how to leverage the Eventing Service to perform a cascade delete operation. When a user is deleted, Couchbase Functions provide a reliable method to delete all the associated documents with the deleted user.

This example requires you to create three buckets: users, metadata and transactions buckets.

For steps to create buckets, see Create Bucket.

Implementation: Create a JavaScript Function that contains an OnDelete handler. The handler listens to data-changes within a specified, users source bucket. When a user within the source bucket gets deleted, the handler executes a routine to remove the deleted user. When the delete operation is complete, all associated documents of the delete users get removed.

Proceed as follows:

  1. From the Couchbase Web Console > Eventing page, click ADD FUNCTION,to add a new Function.

    functions add 4exp3
  2. In the ADD FUNCTION dialog, for individual Function elements, provide the below information:

    • For the Source Bucket drop-down, select the Users that was created for this purpose.

    • For the Metadata Bucket drop-down, select the metadata 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 the associated value.

  3. After providing all the required information 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.

    addfunctions code exp3
  4. Copy the following Function, and paste it in the placeholder code block of the delete_orphaned_txns screen:

    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;
                var del = delete from `transactions` where user_id = TONUMBER($this_user_id);
                del.execQuery();
                log('Deleted Orphaned Transactions for User:', this_user_id);
           }
           catch(e)
           {
               log('Exception:', e)
           }
        }
    }

    After pasting, the screen appears as displayed below:

    ondelete functions

    The OnDelete handler is triggered for user delete transaction. The handler checks if the user_id is less than 10. When this condition is fulfilled, then an N1QL query is triggered to delete all user related information. The handler is then configured to record this delete operation in a Function specific application log file. .

  5. To return to the Eventing screen, click Eventing. The Function delete_orphaned_txns is listed as a defined Function. Currently, it is listed as Undeployed and Paused.

  6. Click Deploy.

  7. From the Confirm Deploy Function dialog, click Deploy Function. From this point, the defined Function is executed on all existing documents and on subsequent mutations.

  8. Navigate to the Couchbase Web Console > Query page. Before deleting a user, a snapshot of Query Result from the users bucket is displayed:

    queryresults ondelerte
  9. The Query Results display users with user_ids from 1 to 10.

  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.

  11. 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;
    query results ondelete
  12. 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.