QUERY A REFERENCE
FIELD.
A reference field in ServiceNow doesn't store the linked record — it stores that record's sys_id. Every interview-grade GlideRecord question about reference fields comes down to that one fact. Here's how to query, traverse, and read those references without firing extra round trips.
1. The basic match: addQuery with a sys_id
Reference fields are matched as plain strings (the sys_id of the referenced row). No special operator needed.
var gr = new GlideRecord('incident');
gr.addQuery('assigned_to', '6816f79cc0a8016401c5a33be04be441');
gr.query();
while (gr.next()) {
gs.info(gr.number);
}2. Dot-walking — filter on the referenced row's fields
You don't need a second GlideRecord. Dot-walk the reference inside addQuery and ServiceNow translates it to a SQL join.
var gr = new GlideRecord('incident');
gr.addQuery('assigned_to.department.name', 'IT');
gr.addQuery('assigned_to.active', true);
gr.query();Watch the depth — each dot is a join. Two levels is fine; four levels on a big table will time out.
3. Read the referenced record with getRefRecord()
Instead of new GlideRecord('sys_user') + get(sys_id), call getRefRecord() on the field. ServiceNow caches it on the row, so subsequent calls are free.
while (gr.next()) {
var user = gr.assigned_to.getRefRecord();
if (user.isValidRecord()) {
gs.info(gr.number + ' → ' + user.email);
}
}4. addJoinQuery — when dot-walking isn't enough
Use addJoinQuery for filtering on a many-to-many or sibling table where dot-walking doesn't go through.
var gr = new GlideRecord('incident');
var join = gr.addJoinQuery('sys_user_grmember', 'assigned_to', 'user');
join.addCondition('group.name', 'Network');
gr.query();Pitfalls that cost interview points
- Comparing a reference to a display value:
addQuery('assigned_to', 'Alex Lee')returns nothing — it expects a sys_id. UseaddQuery('assigned_to.name', 'Alex Lee'). - Reading
gr.assigned_toas a string gets you the sys_id; for the display name, callgr.getDisplayValue('assigned_to'). gr.assigned_to.emailworks in server-side script because of automatic dot-walk, but in a Client Script you must useg_form.getReference('assigned_to', cb)— it's async.- Don't query inside a loop. Replace
while(...) { new GlideRecord('sys_user')...get() }withgetRefRecord()or a single dot-walked addQuery.
Practice this
Six timed GlideRecord questions exercise exactly this material — addQuery, dot-walking, and getRefRecord() — under interview pressure.