Skip to content

Commit fa447a4

Browse files
authored
feat: Add duplicate combination script and update README (#1875)
* Rename script.js to findDuplicatesBySingleField.js * Create findDuplicatesByCombination.js * Update readme.md, combine both scripts into 1 readme
1 parent 56bfa43 commit fa447a4

File tree

3 files changed

+117
-5
lines changed

3 files changed

+117
-5
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* Finds and reports records that have duplicate values across a combination of specified fields instead of a single field
3+
* Useful for finding for example duplicate items where unique key is not just 1 field
4+
*/
5+
6+
// --- UPDATE ONLY THE VALUES BELOW ---
7+
var tableName = 'cmdb_model'; // ADD: The table you want to check for duplicates.
8+
var fieldNames = ['name', 'model_number', 'manufacturer']; // ADD: An array of fields that create the unique combination.
9+
10+
// --- DO NOT EDIT BELOW THIS LINE ---
11+
findDuplicateCombinations(tableName, fieldNames);
12+
13+
function findDuplicateCombinations(tableName, fieldNames) {
14+
/**************************************/
15+
/*** Basic Error Handling ***/
16+
/**************************************/
17+
18+
// Check if the table exists
19+
if (!gs.tableExists(tableName)) {
20+
gs.print('Error: Table "' + tableName + '" does not exist.');
21+
return;
22+
}
23+
24+
// Check if fieldNames is a valid, non-empty array
25+
if (!Array.isArray(fieldNames) || fieldNames.length === 0) {
26+
gs.print('Error: The "fieldNames" variable must be an array with at least one field.');
27+
return;
28+
}
29+
30+
// Check if all specified fields exist on the table
31+
var gr = new GlideRecord(tableName);
32+
gr.initialize();
33+
for (var i = 0; i < fieldNames.length; i++) {
34+
var currentField = fieldNames[i];
35+
if (!gr.isValidField(currentField)) {
36+
gs.print('Error: The field "' + currentField + '" does not exist on the "' + tableName + '" table.');
37+
return;
38+
}
39+
}
40+
41+
/***************************************/
42+
/*** Find Duplicate Combinations ***/
43+
/***************************************/
44+
var duplicateJson = {}; // Stores the duplicate records and their counts
45+
var duplicateGroupCount = 0; // Counts the number of groups of duplicates
46+
47+
var duplicateAggregate = new GlideAggregate(tableName);
48+
duplicateAggregate.addAggregate('COUNT');
49+
50+
// Loop through the array to group by each field, creating the combination
51+
for (var j = 0; j < fieldNames.length; j++) {
52+
var field = fieldNames[j];
53+
duplicateAggregate.groupBy(field);
54+
duplicateAggregate.addNotNullQuery(field); // Ignore records where any part of the combination is empty
55+
}
56+
57+
duplicateAggregate.addHaving('COUNT', '>', 1); // More than 1 means it is a duplicate combination
58+
duplicateAggregate.query();
59+
60+
while (duplicateAggregate.next()) {
61+
duplicateGroupCount++;
62+
var combinationDisplay = [];
63+
64+
for (var k = 0; k < fieldNames.length; k++) {
65+
var fieldName = fieldNames[k];
66+
var fieldValue = duplicateAggregate.getDisplayValue(fieldName) || duplicateAggregate.getValue(fieldName);
67+
combinationDisplay.push(fieldName + ': "' + fieldValue + '"');
68+
}
69+
70+
var displayKey = combinationDisplay.join(', ');
71+
var countInGroup = duplicateAggregate.getAggregate('COUNT');
72+
duplicateJson[displayKey] = countInGroup;
73+
}
74+
75+
/***************************************/
76+
/*** Print the Results ***/
77+
/***************************************/
78+
79+
// No duplicates found
80+
var fieldCombinationString = '"' + fieldNames.join('", "') + '"';
81+
if (Object.keys(duplicateJson).length === 0) {
82+
gs.print('No duplicates found for the field combination [' + fieldCombinationString + '] on table "' + tableName + '".');
83+
return;
84+
}
85+
86+
// Duplicates were found
87+
gs.print("Found " + duplicateGroupCount + " groups of duplicates based on the combination [" + fieldCombinationString + "]:");
88+
89+
for (var key in duplicateJson) {
90+
gs.print('Combination {' + key + '} has ' + duplicateJson[key] + ' occurrences.');
91+
}
92+
}

Server-Side Components/Background Scripts/Duplicate Finder/readme.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
## ServiceNow Duplicate Record Finder
2-
A simple server-side script for ServiceNow that finds and reports on duplicate values for any field on any table. It uses an efficient GlideAggregate query and formats the results into a clean, readable report.
3-
1+
# ServiceNow Duplicate Record Finder
2+
A simple server-side script for ServiceNow that finds and reports on duplicate values for any field on any table. It uses an efficient `GlideAggregate` query.
3+
## Find Duplicates by Single Field - `findDuplicatesBySingleField.js`
4+
This finds duplicates based on a single field which matches
45
### How to Use
56
This script is designed to be run in **Scripts - Background** or as a Fix Script.
67
1. Navigate: Go to **System Definition > Scripts - Background** (or type sys.scripts.do in the filter navigator).
7-
2. Copy Script: Copy the entire contents of the script.js file.
8+
2. Copy Script: Copy the entire contents of the `findDuplicatesBySingleField.js` file.
89
3. Paste and Configure: Paste the script into the "Run script" text box. Add the table to search in `tableName` and the field to search for duplicates in `fieldName`
910
```js
1011
// Update ONLY below values to find duplicates
@@ -22,6 +23,25 @@ This script is designed to be run in **Scripts - Background** or as a Fix Script
2223
var fieldName = 'short_description';
2324
```
2425

25-
2626
4. Run Script: Click the "Run script" button. The results will be displayed on the screen below the editor.
2727

28+
## Find Duplicates by Field Combination - `findDuplicatesByCombination.js`
29+
This is a more powerful script that finds duplicate records based on a unique combination of one or more fields.
30+
31+
### How to use
32+
This script is also designed to be run in **Scripts - Background**
33+
1. Navigate: Go to **System Definition > Scripts - Background**
34+
2. Copy Script: Copy the entire contents of the `findDuplicatesByCombination.js` file.
35+
3. Paste and Configure: Paste the script into the "Run script" text box. Update the `tableName` field and the `fieldNames` array. The `fieldNames` variable is an array, so even a single field must be enclosed in square brackets `[]`
36+
37+
```js
38+
// --- UPDATE ONLY THE VALUES BELOW ---
39+
var tableName = '<table_name>'; // The table you want to check.
40+
var fieldNames = ['field_1', 'field_2']; // An array of fields for the unique combination.
41+
```
42+
43+
For example, to find models with the same name, model number and manufacturer
44+
```js
45+
var tableName = 'cmdb_model';
46+
var fieldNames = ['name', 'model_number', 'manufacturer'];
47+
```

0 commit comments

Comments
 (0)