Domain separated query to fetch records from parent when child domain doesn't have the record?

Kiran52
ServiceNow Employee
ServiceNow Employee

I have requirement for an API to query records by domain. If a record isn't overriden in child domain then it should get it form the parent.

 

For example -> TOP/ACME/ACME Child is the hierarchy.

the API will receive the domain_id of "ACME Child". If there is no overriding record in that domain, then check "ACME" . If "ACME" doesn't have an overriding record, then get it from TOP and so on.

 

Here's my current code

function getRecordByDomain(tableName, domainId) {
    var gr = new GlideRecord(tableName);
    gr.addQuery('sys_domain', domainId);
    gr.queryNoDomain();
    while (gr.next()) {
        gs.print(gr.name);
    }
}

 

But this code is only querying records in the specified child domain "ACME Child" but not looking at the parent or global etc.

 

How do i make it query the records in parent domain if the records aren't overridden in child? This is a function written in a  global script include and called from a rest api. there is no session domain applicable here. we have to use the given domainId only.

2 REPLIES 2

pratikjagtap
Giga Guru

Hi @Kiran52 ,

 

  • Builds the domain hierarchy upwards (e.g., ACME Child → ACME → TOP),
  • Queries all records (with .queryNoDomain()),
  • Filters them manually to find the first matching record in the hierarchy

function getRecordByDomain(tableName, domainId) {
var domainHierarchy = getDomainHierarchy(domainId); // ACME Child → ACME → TOP
var foundRecords = {}; // Map to hold domainId → record

// Step 1: Query all records across domains
var gr = new GlideRecord(tableName);
gr.queryNoDomain(); // We’ll manually filter based on sys_domain

// Step 2: Store records by their domain
while (gr.next()) {
var domId = gr.sys_domain.toString();
if (!foundRecords[domId]) {
foundRecords[domId] = gr.getUniqueValue(); // store sys_id or whole record if needed
}
}

// Step 3: Return the first record found in the domain hierarchy (child to parent)
for (var i = 0; i < domainHierarchy.length; i++) {
var dId = domainHierarchy[i];
if (foundRecords[dId]) {
var result = new GlideRecord(tableName);
if (result.get(foundRecords[dId])) {
return result; // return the GlideRecord
}
}
}

// Optional: fallback to global domain
if (foundRecords['global']) {
var globalRec = new GlideRecord(tableName);
if (globalRec.get(foundRecords['global'])) {
return globalRec;
}
}

return null; // no match found
}

 

Domain Hierarchy Builder Function:

 

function getDomainHierarchy(domainId) {
var hierarchy = [];
var domainGR = new GlideRecord('sys_domain');
if (domainGR.get(domainId)) {
do {
hierarchy.push(domainGR.sys_id.toString());
} while (domainGR.parent && domainGR.parent.getRefRecord() && domainGR = domainGR.parent.getRefRecord());
}
hierarchy.push('global'); // Always check global last
return hierarchy;
}

 

Example Usage from REST API Script Include:

 

var result = getRecordByDomain('cmn_location', 'd1234567890abcdef');
if (result) {
response.setBody({ name: result.name, sys_id: result.sys_id.toString() });
} else {
response.setStatus(404);
response.setBody({ error: "No matching record found in domain hierarchy" });
}

 

If my response helped, please hit the 👍Thumb Icon and accept the solution so that it benefits future readers.

 

Regards,
Pratik

Kiran52
ServiceNow Employee
ServiceNow Employee

I was hoping for a builtin api/function on gliderecord to query records with hierarchy. As the domain hierarchy is a builtin feature of platform, this doesn't feel like som edge-case that needs us to write all the logic by ourselves