โ† Home
๐Ÿ”ฅ0 DAY
โšก0 XP
Scripting Recipe ยท GlideRecord

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.

Short answer

To query a reference field with GlideRecord, pass the referenced record's sys_id to addQuery(), or dot-walk the reference to filter on the referenced record's own fields. To read the referenced row, call getRefRecord() instead of running a second query.

var gr = new GlideRecord('incident');
gr.addQuery('assigned_to', userSysId);          // match by sys_id
gr.addQuery('assigned_to.department.name', 'IT'); // dot-walk filter
gr.query();
while (gr.next()) {
  var user = gr.assigned_to.getRefRecord();     // no extra query
  gs.info(gr.number + ' โ†’ ' + user.email);
}
  • Match: addQuery('field', sys_id) โ€” never the display value.
  • Filter deeper: dot-walk 'field.other_field' (each dot is a join).
  • Read: getRefRecord() server-side, g_form.getReference() client-side.
  • Join tables: addJoinQuery().

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. Use addQuery('assigned_to.name', 'Alex Lee').
  • Reading gr.assigned_to as a string gets you the sys_id; for the display name, call gr.getDisplayValue('assigned_to').
  • gr.assigned_to.email works in server-side script because of automatic dot-walk, but in a Client Script you must use g_form.getReference('assigned_to', cb) โ€” it's async.
  • Don't query inside a loop. Replace while(...) { new GlideRecord('sys_user')...get() } with getRefRecord() or a single dot-walked addQuery.

Practice this

Six timed GlideRecord questions exercise exactly this material โ€” addQuery, dot-walking, and getRefRecord() โ€” under interview pressure.