Toggle menu

bucketHistories()

Description

This function counts histories that match a "bucket". A bucket is a group of histories that can be defined by a history's created or last updated time, by the timestamp of the first or last event in a history, by the timestamp of the first or last event in a history that matches a supplied event filter, or by the value of a field within an event. Additional top level history filters can also be applied before the buckets are created.

Each bucket of matching histories can include a count of the histories in it, and the minimum, maximum, sum and average time (in seconds) between any combination of the history created time, history last updated time, or the timestamp of the first or last event in the history. Histories can be grouped by label within their buckets.

Parameters

NameTypeDescription
datasourceString, optionalThe name of the datasource from where the histories will be retrieved. This parameter overrides the parameter in the worker configuration which in turn overrides the default datasource
filterFilter-object, optionalA filter object to set which histories will be bucketed. See Filter Objects for more information. The filter can only access top level history properties (ie it cannot access subject or event values)
sealedBoolean, optionalIf true, then only histories that have been switched into read-only mode will be searched. If false then only writable histories will be searched. If sealed is not supplied, then all histories will be searched
eventfilterFilter-object, optionalUse a filter described in Filter Objects to select one event from a history. This event can then be used in an event or EVENT.<fieldname> bucket or in the timer
matchlasteventBoolean, optionalIf true the eventfilter will select the last event in the history that matches the filter. Default false (ie select the first matching event). If an eventfilter isn't set, selects the first/last event in the history
bucketsObject, requiredDefine a set of ranges and count/aggregate the histories in each range. If histories are returned that don't match a bucket key, they are placed in a no_value bucket
 buckets.keyString, requiredEither created, lastupdated, event or EVENT.<fieldname>
buckets.ranges[n].nameString, requiredA name for the bucket, returned with the results
buckets.ranges[n].fromInteger or string, requiredThe beginning of the range (inclusive). The keys created, lastupdated and event require integers representing ms since the epoch. If using EVENT.<fieldname> set a value compatible with what you are querying. If you don't set an event filter event will select the first/last event in the history
buckets.ranges[n].toInteger or string, requiredThe beginning of the range (inclusive). The keys created, lastupdated and event require integers representing ms since the epoch. If using EVENT.<fieldname> set a value compatible with what you are querying. ;If you don't set an event filter event will select the first/last event in the history
groupbyString or array of strings, optionalA single history label (labela/labelb/labelc/labeld/labele) or array of labels. Results will be grouped by matching label(s) and counts/aggregates returned for each group
timerObject, optionalA count in seconds between the from and to properties
 timer.fromString, requiredEither created, lastupadted or event. Count from a history's created or last updated time, or the timestamp of the first/last event in the history, or the timestamp of the event that matches the eventfilter
 timer.toString, requiredEither created, lastupadted or event. Count to a history's created or last updated time, or the timestamp of the first/last event in the history, or the timestamp of the event that matches the eventfilter. Note that the first event in a history is written at exactly the same time as the history, so counting from created to the first event won't be very useful
aggregateString or array of strings, optionalAggregation performed on the value of each timer in each bucket:
count - a count of the histories
min - the shortest timer
max - the longest timer
avg - the mean of the timers
sum - the sum of the timers
getsqlBoolean, optionalIf true the return structure will include an element called "sql" which contains the query and the parameters which were used to retrieve the history data from the database. This option returns a large amount of data and is intended for testing and debugging
getastBoolean optionalIf true the query will return the abstract syntax tree generated by the filter and show the ast of the filter after it has been through the optimiser. This parameter is intended for testing and debugging

Returns

An array of objects. Each object represents a bucket. Each bucket will include its name, the requested aggregates, and any labels that have been set as groups. If an event is selected by the filter but it does not contain the field specified in buckets.key=EVENT.<fieldname> then the history is returned in an automatically generated "no_value" bucket.

Examples

The following examples all set a top-level filter to reduce the number of results.

Created Buckets and Timers to Last Updated

This example buckets histories by the month they were created. The timer counts from created until the last updated time. As we're only looking at sealed (complete) histories this timer effectively counts the timespan of each history, which could equate to the length of time a workflow process was running.

function(params, credentials) {
    let resp = this.callWorkerMethod("history", "bucketHistories", {
        "filter": {
            "key": "labela",
            "EQ": "Chained Tasks"
        },
        "sealed": true,
        "buckets": {
            "key": "created",
            "ranges": [
                {
                    "name": "sept18",
                    "from": 1535760000000,
                    "to": 1538265600000
                }, {
                    "name": "oct18",
                    "from": 1538352000000,
                    "to": 1541030399000
                }, {
                    "name": "nov18",
                    "from": 1541030400000,
                    "to": 1543536000000
                }, {
                    "name": "dec18",
                    "from": 1543622400000,
                    "to": 1546300799000
                }, {
                    "name": "jan19",
                    "from": 1546300800000,
                    "to": 1548979199000
                }, {
                    "name": "feb19",
                    "from": 1548979200000,
                    "to": 1551398399000
                }
            ]
        },
        "timer": {
            "from": "created",
            "to": "lastupdated"
        },
        "aggregate": ["count", "min", "max", "sum", "avg"]
    });
    return resp;
}

No histories were found for four of the months so their buckets are not returned. You can see that in September there were seven records with an average duration of 1005 seconds. February was busier, with one record open for almost five days (427910 seconds).

{
    "jsonrpc": "2.0",
    "id": 154,
    "result": {
        "result": {
            "result": [{
                "bucket": "sept18",
                "min": 22,
                "avg": 1005,
                "max": 6780,
                "count": 7,
                "sum": 7036
            }, {
                "bucket": "feb19",
                "min": 2,
                "avg": 338271,
                "max": 427910,
                "count": 10,
                "sum": 3382711
            }]
        },
        "id": "_544",
        "jsonrpc": "2.0"
    }
}

Time to Event

This example finds histories and times how long it took for a particular event to occur - this could represent a first response time. Remember that the very first event in a history has the same timestamp as the history's created time so isn't generally a good event to use, you should create an event filter to select the event you are interested in, in this case an event called "Task 1".

function(params, credentials) {
    let resp = this.callWorkerMethod("history", "bucketHistories", {
        "filter": {
            "key": "labela",
            "EQ": "Chained Tasks"
        },
        "eventfilter": {
            "key": "description",
            "EQ": "Task 1"
        },
        "buckets": {
            "key": "event",
            "ranges": [{          
                "name": "sept18",
                "from": 1535760000000,
                "to": 1538265600000
            }]
        },
        "timer": {
            "from": "created",
            "to": "event"
        },
        "aggregate": ["count", "min", "max", "sum", "avg"]
    });
    return resp;
}

In September there were two instances of the event we're looking for. The quickest was written eighteen seconds after the history was created, the slowest forty-four seconds.

{
    "jsonrpc": "2.0",
    "id": 165,
    "result": {
        "result": {
            "result": [{
                "bucket": "sept18",
                "min": 18,
                "avg": 31,
                "max": 44,
                "count": 2,
                "sum": 62
            }]
        },
        "id": "_594",
        "jsonrpc": "2.0"
    }
}

Event Field Bucket - No Event Filter

In this example the histories include form data. The RADIOGROUP field has the value "1" or "2". Results are bucketed by that value and a timer counts the seconds between created and last updated.

function(params, credentials) {
    let resp = this.callWorkerMethod("history", "bucketHistories", {
        "filter": {
            "key": "labela",
            "EQ": "Chained Tasks"
        },
        "buckets": {
            "key": "EVENT.formData.data.RADIOGROUP",
            "ranges": [{
                    "name": "RADIO1",
                    "from": "1",
                    "to": "2"
                }, {
                    "name": "RADIO2",
                    "from": "2",
                    "to": "3"
                }
            ]
        },
        "timer": {
            "from": "created",
            "to": "lastupdated"
        },
        "aggregate": ["count", "min", "max", "sum", "avg"]
    });
    return resp;
}

The query found seventeen histories. However, because our query didn't set an event filter, it only looked at the first event in each history. Only one event matched the bucket key so sixteen ended up in the no_value bucket.

{
    "jsonrpc": "2.0",
    "id": 141,
    "result": {
        "result": {
            "result": [{
                "bucket": "no_value",
                "min": 2,
                "avg": 190136,
                "max": 427910,
                "count": 16,
                "sum": 3042179
            }, {
                "bucket": "RADIO1",
                "min": 347568,
                "avg": 347568,
                "max": 347568,
                "count": 1,
                "sum": 347568
            }]
        },
        "id": "_490",
        "jsonrpc": "2.0"
    }
}

Event Field Bucket - With an Event Filter

This is a similar query to the one above, but this time we've set an event filter. That means we'll only get back histories that have an event with the set field, and that rather than selecting the first event of the history and trying to place it in a bucket, the query will select the first event in a history that matches the filter, then attempt to place the history in a bucket.

The timer has been set up to count the time between the history being written and the first event that matches the filter being added to it.

function(params, credentials) {
    let resp = this.callWorkerMethod("history", "bucketHistories", {
        "filter": {
            "key": "labela",
            "EQ": "Chained Tasks"
        },
        "eventfilter": {
            "key": "formData.data.RADIOGROUP",
            "GT": ""
        },
        "buckets": {
            "key": "EVENT.formData.data.RADIOGROUP",
            "ranges": [{
                    "name": "RADIO1",
                    "from": "1",
                    "to": "2"
                }, {
                    "name": "RADIO2",
                    "from": "2",
                    "to": "3"
                }
            ]
        },
        "timer": {
            "from": "created",
            "to": "event"
        },
        "aggregate": ["count", "min", "max", "sum", "avg"]
    });
    return resp;
}

The query found fifteen histories that match the event filter and has placed them into two buckets based on the value of the RADIOGROUP field.

{
    "jsonrpc": "2.0",
    "id": 143,
    "result": {
        "result": {
            "result": [{
                "bucket": "RADIO1",
                "min": 0,
                "avg": 108398,
                "max": 350658,
                "count": 13,
                "sum": 1409181
            }, {
                "bucket": "RADIO2",
                "min": 34,
                "avg": 42,
                "max": 51,
                "count": 2,
                "sum": 85
            }]
        },
        "id": "_500",
        "jsonrpc": "2.0"
    }
}

Grouping

The groupby parameter groups histories by one or more matching labels and returns counts/aggregates by group. This example creates buckets by created date and groups the results by labela. It is similar to the first example above (which filtered to one particular history label).

function(params, credentials) {
    let resp = this.callWorkerMethod("history", "bucketHistories", {
        "buckets": {
            "key": "created",
            "ranges": [
                {
                    "name": "sept18",
                    "from": 1535760000000,
                    "to": 1538265600000
                }, {
                    "name": "oct18",
                    "from": 1538352000000,
                    "to": 1541030399000
                }, {
                    "name": "nov18",
                    "from": 1541030400000,
                    "to": 1543536000000
                }, {
                    "name": "dec18",
                    "from": 1543622400000,
                    "to": 1546300799000
                }, {
                    "name": "jan19",
                    "from": 1546300800000,
                    "to": 1548979199000
                }, {
                    "name": "feb19",
                    "from": 1548979200000,
                    "to": 1551398399000
                }
            ]
        },
        "timer": {
            "from": "created",
            "to": "lastupdated"
        },
        "aggregate": ["count", "min", "max", "sum", "avg"],
        "groupby": "labela"
    });
    return resp;
}

The response shows how buckets are created for the set ranges (where they have results) and includes counts for each labela.

{
    "jsonrpc": "2.0",
    "id": 32,
    "result": {
        "result": {
            "result": [{
                "bucket": "oct18",
                "min": 1093,
                "avg": 1093,
                "max": 1093,
                "count": 1,
                "sum": 1093,
                "labela": "Feedback Review"
            }, {
                "bucket": "oct18",
                "min": 57,
                "avg": 2421,
                "max": 3604,
                "count": 3,
                "sum": 7263,
                "labela": "File References Example"
            }, {
                "bucket": "nov18",
                "min": 9211,
                "avg": 595542,
                "max": 1181873,
                "count": 2,
                "sum": 1191084,
                "labela": "Feedback Review"
            }, {
                "bucket": "nov18",
                "min": 3603,
                "avg": 3603,
                "max": 3604,
                "count": 2,
                "sum": 7207,
                "labela": "File References Example"
            }, {
                "bucket": "dec18",
                "min": 131,
                "avg": 1866,
                "max": 3601,
                "count": 2,
                "sum": 3732,
                "labela": "File References Example"
            }, {
                "bucket": "feb19",
                "min": 18,
                "avg": 18,
                "max": 18,
                "count": 1,
                "sum": 18,
                "labela": "File References Example"
            }, {
                "bucket": "feb19",
                "min": 198,
                "avg": 270,
                "max": 308,
                "count": 3,
                "sum": 812,
                "labela": "Object Export Example"
            }]
        },
        "id": "_57",
        "jsonrpc": "2.0"
    }
}

Last modified on 20 November 2023

Share this page

Facebook icon Twitter icon email icon

Print

print icon