The CMDB's data model splits CI identity across multiple tables. While CI names live directly on cmdb_ci, IP addresses are stored in the related cmdb_ci_ip table with a reference back to the CI. Most developers instinctively query cmdb_ci for everything, but IP lookups require the two-step dance: find the IP record first, then get its ci reference. This separation exists because CIs can have multiple IP addresses, and ServiceNow needs to track each one individually with its own discovery metadata.
When to use this
- Business Rules that need to correlate incidents or changes with specific CIs
- Discovery integrations where you have hostnames or IP addresses from external tools
- Scheduled jobs processing CSV imports with mixed identifier types
- Fix scripts cleaning up CMDB data where you need to verify CI existence first
When NOT to use this
- Client scripts β use GlideAjax to call this Script Include instead
- Inside loops over large datasets β you'll create N+1 query problems
- When you need fuzzy matching β use
CONTAINSorSTARTSWITHqueries instead - When processing discovery queue items β use the built-in CMDB APIs for better performance
Key behaviors and gotchas
- IP addresses in
cmdb_ci_ipare stored as strings, not parsed β '192.168.1.01' != '192.168.1.1' - CIs can have multiple IP records β
setLimit(1)prevents accidentally returning arrays - Name searches are case-sensitive by default unless your instance has case-insensitive collation
- Domain separation applies to both tables β cross-domain CI lookups may fail silently
- The
namefield oncmdb_ciis indexed, butip_addressoncmdb_ci_ipmay not be β check your table indexes
Never query cmdb_ci with addQuery('ip_address', ...) β that field doesn't exist on the CI table. You'll get zero results and no error message. Always use the two-step lookup through cmdb_ci_ip first.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros β scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.