Skip to content
40 changes: 40 additions & 0 deletions Core ServiceNow APIs/GlideAggregate/SimpleGlideAggregate/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
SimpleGlideAggregate Utility
**Overview**
SimpleGlideAggregate is a developer utility Script Include for ServiceNow that provides a simplified, chainable API around the native GlideAggregate class. It abstracts complexities of writing aggregation queries and returns results in an easy-to-use JavaScript object format.
Because OOTB glideAggregate API is little bit different so I tried to create a new function with a simper version.
**Purpose**
Simplify aggregate queries such as COUNT, SUM, MIN, and MAX for developers, especially those less familiar with GlideAggregate methods.
Provide an intuitive interface for common aggregation operations with chaining support.
Facilitate viewing aggregate results alongside individual records matching the same criteria for better analysis.

**Sample Usage of the functions :**
var sga = new SimpleGlideAggregate('incident');

// Build query and add all supported aggregates
var results = sga
.addQuery('active', true) // Filter: active incidents only
.addQuery('priority', '>=', 2) // Priority 2 or higher
.count() // Count matching records
.sum('duration') // Sum of duration field instead of impact
.min('priority') // Minimum priority value in results
.max('sys_updated_on') // Most recent update timestamp
.execute();

gs.info('Aggregate Results:');
gs.info('Count: ' + results.COUNT);
gs.info('Sum of Duration: ' + (results.SUM_duration !== undefined ? results.SUM_duration : 'N/A'));
gs.info('Minimum Priority: ' + (results.MIN_priority !== undefined ? results.MIN_priority : 'N/A'));
gs.info('Most Recent Update (max sys_updated_on timestamp): ' + (results.MAX_sys_updated_on !== undefined ? results.MAX_sys_updated_on : 'N/A'));

// Optionally fetch some matching record details to complement the aggregate data
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.addQuery('priority', '>=', 2);
gr.orderByDesc('sys_updated_on');
gr.setLimit(5);
gr.query();

gs.info('Sample Matching Incidents:');
while (gr.next()) {
gs.info('Number: ' + gr.getValue('number') + ', Priority: ' + gr.getValue('priority') + ', Updated: ' + gr.getValue('sys_updated_on'));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
var SimpleGlideAggregate = Class.create();
SimpleGlideAggregate.prototype = {
initialize: function(tableName) {
if (!tableName) {
throw new Error("Table name is required.");
}
this._table = tableName;
this._ga = new GlideAggregate(tableName);
this._fields = [];
this._conditionsAdded = false;
},

/**
* Adds a query condition.
* Usage: addQuery('priority', '=', '1') or addQuery('active', true)
*/
addQuery: function(field, operator, value) {
if (value === undefined) {
this._ga.addQuery(field, operator);
} else {
this._ga.addQuery(field, operator, value);
}
this._conditionsAdded = true;
return this;
},

/**
* Adds COUNT aggregate.
*/
count: function() {
this._fields.push({type: 'COUNT', field: null});
return this;
},

/**
* Adds SUM aggregate on a field.
*/
sum: function(field) {
if (!field) throw new Error("Field name required for sum.");
this._fields.push({type: 'SUM', field: field});
return this;
},

/**
* Adds MIN aggregate on a field.
*/
min: function(field) {
if (!field) throw new Error("Field name required for min.");
this._fields.push({type: 'MIN', field: field});
return this;
},

/**
* Adds MAX aggregate on a field.
*/
max: function(field) {
if (!field) throw new Error("Field name required for max.");
this._fields.push({type: 'MAX', field: field});
return this;
},

/**
* Executes the aggregate query and returns results as an object.
* Keys are aggregate type or type_field (for field aggregates).
*/
execute: function() {
var self = this;

if (this._fields.length === 0) {
throw new Error("At least one aggregate function must be added.");
}

this._fields.forEach(function(agg) {
if (agg.field) {
self._ga.addAggregate(agg.type, agg.field);
} else {
self._ga.addAggregate(agg.type);
}
});

this._ga.query();

var results = {};
if (this._ga.next()) {
this._fields.forEach(function(agg) {
var key = agg.field ? agg.type + '_' + agg.field : agg.type;
var value = agg.field ? self._ga.getAggregate(agg.type, agg.field) : self._ga.getAggregate(agg.type);
results[key] = agg.type === 'COUNT' ? parseInt(value, 10) : parseFloat(value);
});
} else {
// No rows matched, all aggregates 0 or null
this._fields.forEach(function(agg) {
var key = agg.field ? agg.type + '_' + agg.field : agg.type;
results[key] = 0;
});
}

return results;
},

type: 'SimpleGlideAggregate'
};
Loading