Now, this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning. — Winston Churchill
// Simple counting function // After every update to travel sample, keep track of the total number of documents of each type. function OnUpdate(doc, meta) { try { // Issue SELECT statement to get the counts. var ginfo = SELECT type, COUNT(type) typecount FROM `travel-sample` WHERE `type` IS NOT MISSING GROUP BY type; // loop through the resultset for (var val of ginfo) { var ckey = "trcount" + val.type; // Create the document key-string. var vtype = val.type; var vtc = val.typecount; // get the type, count // do the update. UPDATE T1 USE KEYS[$ckey] SET type = $vtype, typecount =$vtc; } } catch(e) { log(e); } }
Statement Type | Eventing Function Invoked |
SELECT | None |
INSERT | OnUpdate(). The function is invoked once per document inserted. Simple insert inserts a single document. Inserts can have multiple documents using multiple documents in the VALUES clause or can insert multiple documents via INSERT INTO…SELECT statement. |
UPDATE | OnUpdate() is invoked once per document updated, except when multiple updates on the same document is deduped into a single update. Update statement can update multiple documents. |
UPSERT | OnUpdate(). The behavior is similar to INSERT. |
DELETE | OnDelete(). Invoked once per documented deleted. |
MERGE | OnUpdate() and/or OnDelete() depending on the insert, update, and delete actions. |
CREATE INDEX, DROP INDEX, EXPLAIN, PREPARE, GRANT, REVOKE | No eventing function is invoked. |
EXECUTE | Depends on the type of the statement executed. |
Statement | Use cases for N1QL statements in Eventing Functions |
CREATE INDEX | Since the schema is flexible, you could potentially inspect the data often/periodically to detect new fields and then create indexes on it. |
DELETE | Cascade deletes. |
DROP INDEX | A corollary to the CREATE INDEX use case. |
INFER | Periodic introspection of the bucket for the structure. Then take action (validate, create index, update the data model) if necessary. |
INSERT | Maintaining referential data (eventually).
Updating other documents with references to this data. E.g Data from a new zip, state, etc.
Data copy (fully or partially) to secondary/tertiary documents. Similar to post-trigger action. |
MERGE | Keep the secondary data in sync. |
SELECT | Fetch any data, run any reports periodically, etc.
Check for various things like data quality, data validity,
When you do know the target document key, use the built-in direct document references. See examples at: https://docs.couchbase.com/server/5.5/eventing/eventing-examples.html |
UPSERT | Keeping secondary/tertiary data in sync.
Similar to post-trigger action. |
UPDATE | Keeping secondary/tertiary data in sync.
Similar to post-trigger action. |
select meta().id, * from execute S1; [ { "S1": { "name": "Joe Smith", "zip": "94501" }, "id": "Joe::94040" }, { "S1": { "name": "John Smith", "zip": "94040" }, "id": "John::94040" } ] select meta().id, * from S2; [ { "S2": { "name": "Joe Smith", "zip": "94501" }, "id": "Joe::94040" }, { "S2": { "name": "John Smith", "zip": "94040" }, "id": "John::94040" } ] select meta().id, * from T1; <No data>
function OnUpdate(doc, meta) { } function OnDelete(meta) { try { var myid = meta.id; //Insert into the bucket of INSERT INTO T1 VALUES(UUID(), {"type" : "deleted", "docid":$myid}); //Cascade delete DELETE FROM S2 USE KEYS [$myid]; } catch(e) { log(e); } } After creating the function above, the application Runs the following: DELETE FROM S1 WHERE zip = "94040"; // One document was deleted. SELECT meta().id, * from S1; // one document just got deleted. There should be only one document remaining. [ { "S1": { "name": "Joe Smith", "zip": "94501" }, "id": "Joe::94040" } ] SELECT meta().id, * from T1; // We should see a log of the deleted [ { "T1": { "docid": "John::94040", "type": "deleted" }, "id": "2dc9b33d-3cd4-422e-af9c-b0c664c4660f" } ] SELECT meta().id, * FROM S2; // We should only see one document due to the effect of cascade delete from the the function [ { "S2": { "name": "Joe Smith", "zip": "94501" }, "id": "Joe::94040" } ]
function OnUpdate(doc, meta) { try { var stattime = SELECT lastupdate FROM T1 USE KEYS ["trstattime"]; for (var t of stattime) { var lt = t.lastupdate; var d = new Date(); var n = d.getTime(); // Every 10 minutes or more if ((n - lt) > (1000 * 60 * 10)) { UPDATE T1 USE KEYS["trstattime"] SET lastupdate = NOW_MILLIS() ; var ginfo = SELECT type, count(type) typecount FROM `travel-sample` WHERE `type` IS NOT MISSING GROUP BY type; for (var val of ginfo) { var ckey = "trcount::" + val.type; var vtype = val.type; var vtc = val.typecount; UPDATE T1 USE KEYS[$ckey] SET type = $vtype, typecount = $vtc; } } } } catch(e) { log(e); } }