メインコンテンツへスキップ
見出し画像

addQueryとaddOrCondition:AND/ORをコードで組む


    開発ハンズオンシリーズの6回目へようこそ。前回の④では、一覧画面で作った絞り込みを、そのまま文字列としてコードに持ち込む「エンコードクエリ」を扱いました。active=true^priority=1 という、あの独特の一行ですね。今回はその同じ条件を、GlideRecord のメソッドを積み重ねて「コードで組む」やり方に進みます。文字列を貼るのも便利ですが、条件を変数から動的に足したいときは、コードで組めるほうが何かと素直ですよ。

    ①のGlideRecord では検索と更新を、Scripts - Background で動かしてきました。③のドット・ウォーク では参照先の辿り方を、同じく Scripts - Background で動かしてきました。基本の検索がひととおり手になじんだところで、今回は条件の「組み立て方」に一歩踏み込みます。AND(かつ)と OR(または)を、コードでどう書き分けるか。ここが今日の主役です。

    うれしいのは、コードで組んだ条件を getEncodedQuery() という一手で文字列に変換できる点です。④で覚えたエンコードクエリと、今回のコードは、いつでも行き来できます。画面で作った文字列をコードに貼るのも、コードで組んで文字列を確かめるのも、どちらも自由自在。この橋渡しまで含めて、今日で一段落つけましょう。

    この記事は、ServiceNow の PDI(Personal Developer Instance、無料の個人検証環境)Zurich リリース・OOTB(初期設定)で実機実行した記録です。コードの出力はすべて Scripts - Background で流した結果で、件数は REST でも二重確認しました(確認日 2026-07-19)。本番環境では実行しないでください。件数は執筆時点の値で、インスタンスによって変わります。

    コードで条件を組むと、何が変わるか

    ④のエンコードクエリは、画面で作った絞り込みをコピーして貼るだけで動く手軽さが魅力でした。では、なぜわざわざコードで組む書き方も覚えるのでしょうか。理由はいくつかありますが、いちばんは「条件を動的に組み立てられる」ところにあります。決め手はそこです。

    たとえば、ユーザーが選んだ優先度だけで絞りたいとき、その値は実行するまで決まりません。文字列を手で書いておく方式だと、こういう場面はやや窮屈です。addQuery('priority', 選ばれた値) のように変数を渡せば、実行時の値でそのまま検索が走ります。Business Rule や Script Include で条件を組む実務では、この「その場で組み立てる」力がよく効きます。

    もうひとつ、コードで組む良さは読みやすさにも表れます。長いエンコード文字列は、^ や ^OR が続くと、どこで条件が切れているのかを目で追いにくくなりがちです。addQuery を1行ずつ並べれば、条件のひとつひとつが行として立ち上がり、後から読み返す人にも意図が伝わりやすい。半年後の自分が見直す場面まで考えると、この見通しのよさは地味に効いてきます。さっと貼るだけの文字列が向く場面もあるので、両方を知って場面で選べるのがいちばん心強いですね。

    今日の道具立てはシンプルです。AND は addQuery を重ねるだけ、OR は addOrCondition を足すだけ、候補が複数あるなら IN で列挙するだけ。そして組んだ条件は getEncodedQuery() でいつでも文字列に直せます。まずは AND から、実機で一つずつ確かめましょう。

    addQuery を重ねると AND

    最初は AND です。「アクティブで、なおかつ優先度が 1(Critical)のインシデント」を数えてみましょう。条件を2つ足して、件数と、その条件のエンコード文字列を出します。

    var gr = new GlideRecord('incident');
    gr.addQuery('active', true);
    gr.addQuery('priority', 1);
    gr.query();
    gs.info('active=true AND priority=1 : ' + gr.getRowCount() + ' 件');
    gs.info('encoded : ' + gr.getEncodedQuery());


    画像

    結果は 16件 でした。エンコード文字列は active=true^priority=1。ポイントは、addQuery を2回呼んだだけで、2つの条件が AND(両方を満たす)でつながっている点です。①でも触れたとおり、addQuery は何本重ねても、すべて AND で結ばれます。OR を書きたいときだけ、次の節の別のやり方を使う、と覚えておくと迷いません。

    getEncodedQuery() の出力にも注目してください。コードで組んだ条件が、④で見た ^ 区切りの文字列にそのまま化けています。^ が AND の区切りでしたね。コードと文字列は、同じ条件の二つの姿にすぎません。この16件は、①で見た「active な優先度1」の件数ともぴたりと一致しました。別の回、別のやり方で数えても同じ数にたどり着く。実測が噛み合うと、安心して先へ進めます。気持ちいいですね。

    なぜ addQuery を重ねると自動で AND になるのか、少しだけ補っておきます。ふだんの検索では「あれも、これも満たすもの」を探す場面が圧倒的に多いからです。ServiceNow は、条件を足していく標準の動きを、その AND に寄せています。OR は「どちらかでよい」という特別な形なので、addOrCondition という別の一手をあえて用意している。この設計を頭に置くと、ふだんは addQuery を並べるだけ、OR がほしいときだけ一手間、というリズムが自然と身につきますよ。

    getEncodedQuery() のもうひとつの使いどころは、コードの答え合わせです。組んだつもりの条件が、思ったとおりに効いているか。実行のあとに文字列を出しておけば、active=true^priority=1 のような形で、条件の全体像を一目で確かめられます。件数が想定と食い違ったとき、まずこの文字列に目をやれば、どこがずれているのか当たりをつけやすい。デバッグの入口として、覚えておいて損はありませんよ。

    addOrCondition で OR

    次は OR です。「優先度が 1、または 5(Planning)」のように、どちらかを満たせばよい条件を組みます。ここで登場するのが addOrCondition です。

    var gr = new GlideRecord('incident');
    var qc = gr.addQuery('priority', 1);
    qc.addOrCondition('priority', 5);
    gr.query();
    gs.info('priority=1 OR priority=5 : ' + gr.getRowCount() + ' 件');
    gs.info('encoded : ' + gr.getEncodedQuery());


    画像

    結果は 49件。この49という数字は、④で priority=1^ORpriority=5 という文字列を投げたときと同じ件数です。文字列で書いても、コードで組んでも、行き着く先は同じ。ここでも二つの姿がそろいました。

    書き方のコツは1行目にあります。gr.addQuery('priority', 1) は、ただ条件を足すだけでなく、その条件を表すオブジェクト(QueryCondition)を戻り値として返す点がミソです。それを qc で受け取ります。qc.addOrCondition('priority', 5) と続けると、「priority=1 に、priority=5 という別の選択肢を重ねる」という指定になります。OR は本体の gr に足すのでなく、特定の条件の戻り値に付けます。この一点さえ押さえれば、OR で迷うことはもうありません。

    ひとつ正直に書いておきます。エンコード文字列を見ると priority=1^ORpriority=5.0 と、末尾に .0 が付いていました。priority は10進の数値項目なので、渡した 5 が 5.0 という文字列として表現されたためです。件数には影響しませんが、「5 のはずが 5.0 になっている」と一瞬とまどいやすい箇所なので、実測のまま書き残しておきます。正直がいちばんです。

    OR が実務で効く場面も、具体で押さえておきましょう。たとえば「優先度が Critical か High のものだけを、対応者へ一度に知らせたい」。こういう「どれかに当てはまれば拾う」条件は、日々の運用でよく出てきます。addOrCondition を使えば、その「または」をコードで素直に表せます。ひとつの項目のなかで候補を並べたいときは、まずこの形を思い出してください。候補がさらに増えてきたら、次の節の IN に切り替えると、もっと短く収まります。

    AND の中に OR

    AND と OR を組み合わせると、もう少し実務らしい条件になります。「アクティブで、なおかつ優先度が 1 か 2 のどちらか」を組んでみましょう。active は必ず満たしつつ、優先度は1か2のどちらでもよい、という形です。

    var gr = new GlideRecord('incident');
    gr.addQuery('active', true);
    var qc = gr.addQuery('priority', 1);
    qc.addOrCondition('priority', 2);
    gr.query();
    gs.info('active AND (p1 OR p2) : ' + gr.getRowCount() + ' 件');
    gs.info('encoded : ' + gr.getEncodedQuery());


    画像

    結果は 20件 でした。内訳を考えると腑に落ちます。active な優先度1が16件、active な優先度2が4件。合わせて20件で、ちょうど数が合いました。エンコード文字列は active=true^priority=1^ORpriority=2.0 です。

    ここでのしくみは、OR を付ける相手にあります。addOrCondition('priority', 2) を足したのは active の条件でなく、priority=1 を表す qc のほうでした。すると active との AND を保ったまま、priority の1と2がひとつの選択肢としてまとまってくれます。もし OR を active 側に付けたら、意味はまるで変わってしまう。どの条件に OR をぶら下げるかで結果が動く、という感覚が、ここでつかめると思います。


    画像

    図は、今日のコードと、それが吐き出すエンコード文字列の対応を並べたものです。左のメソッドの積み重ねが、右の ^ や ^OR の文字列に、そのまま翻訳されているのが見て取れます。なお、^OR がどこまでを一つのまとまりとして結ぶか、その厳密な規則は、ここでは実測できた20件という事実にとどめておきます。細かな結合ルールを暗記するより、「付けた相手に OR がぶら下がる」と手で確かめるほうが、実務では役に立ちますよ。そこが要点です。

    この「AND を保ったまま、一部だけ OR」という形は、実務でとても出番が多いものです。土台になる絞り込み(たとえば active なもの、担当が自分のもの)は必ず効かせつつ、そのなかで優先度や状態のいくつかを候補として許す。日々のダッシュボードや通知の条件は、たいていこの構造で成り立っています。付け先さえ取り違えなければ、AND の土台は崩れません。安心して、必要な OR だけをぶら下げてください。

    IN でもっと短く

    さきほどの「優先度1か2」は、実はもっと短く書けます。IN という演算子を使う方法です。候補をカンマ区切りで並べて、一度に指定できます。

    var gr = new GlideRecord('incident');
    gr.addQuery('active', true);
    gr.addQuery('priority', 'IN', '1,2');
    gr.query();
    gs.info('active AND priority IN 1,2 : ' + gr.getRowCount() + ' 件');
    gs.info('encoded : ' + gr.getEncodedQuery());


    画像

    結果は 20件。ひとつ前の節と、まったく同じ数にそろいました。エンコード文字列は active=true^priorityIN1,2 と、こちらもすっきりしています。.0 も付いていませんね。

    書き方のポイントは、addQuery の第2引数に演算子を渡せるところにあります。addQuery('priority', 'IN', '1,2') は、「priority が 1 か 2 のいずれか」という指定です。候補が3つ4つと増えても、'1,2,3,4' と値を足すだけ。OR を2本、3本と書き足していくより、ずっと読みやすく短く収まります。①で addQuery('priority', '<=', 2) のように演算子を渡せると触れましたが、IN もその仲間ですね。等しい・以下・含む、といった比べ方を、第2引数の演算子で自在に選べます。

    同じ20件を、OR で組んでも IN で組んでも出せる。書き方に幅があるのは、実務ではありがたい話です。「候補のどれか」を表したいなら IN が読みやすく、別項目どうしの OR を混ぜたいなら addOrCondition が向いています。場面に合わせて、短く書けるほうを選ぶのが得策です。迷わなくて済みますね。

    IN のありがたみは、候補が増えるほど際立ちます。もし「優先度が 1 か 2 か 3」を OR だけで表そうとすると、選択肢の数だけ条件を足していく手間がかかりがちです。IN なら '1,2,3' と値を一つ増やすだけ。ぐっと短く収まります。状態(state)の複数指定のように、選択肢のなかから「このいくつか」を拾う条件は、日々の運用で本当によく出てきます。IN の書き味を覚えておくと、レビューやメンテのときにも読み手がすっと理解できますよ。

    コードと文字列は行き来できる

    ここまでで、コードで組んだ条件が getEncodedQuery() で文字列になる様子を、何度も見てきました。この getEncodedQuery は「コード → 文字列」への変換です。そして④で扱った addEncodedQuery は、その逆で「文字列 → コード」への持ち込みでした。二つは、ちょうど向きが反対の一対になっています。シンプルな関係です。

    だから、行き来はどちらの向きからでも成り立ちます。一覧画面で絞り込みを作り、右クリックの Copy query で文字列を取り出し、それを gr.addEncodedQuery('...') に貼れば、画面の条件がそっくりコードで動いてくれます。逆の道もなめらかです。今日のようにコードで条件を組み立て、getEncodedQuery() で文字列に直し、その一行を一覧画面の URL やフィルタに貼れば、画面側で同じ絞り込みがよみがえります。

    この橋渡しが分かると、開発の途中でとても楽になります。複雑な条件は、まず画面のフィルタで組んで動きを確かめ、Copy query でコードへ持ち込む。コードで組んだ条件が本当に正しいか不安なときは、getEncodedQuery で文字列にして、画面に貼って件数を目で確かめる。コードと画面のどちらか片方に閉じこもらず、行ったり来たりしながら確かめられる。これが、エンコードクエリを覚えておくいちばんの見返りだと思います。

    もう少し踏み込むと、この行き来はチームで働くときにも助けになります。エンコード文字列は、そのままチャットやチケットに貼って共有できる一行だからです。「この条件で調べてほしい」と誰かに頼むとき、active=true^priorityIN1,2 の一行を渡せば、相手は画面にもコードにも同じ条件を再現できます。コードと文字列が地続きだと分かっていれば、共有はいつでも軽い一行で済む。現場では、この小回りのよさがじわりと効いてきます。

    つまずきやすいところ

    今日の内容で、最初に引っかかりやすい点を先回りで挙げておきます。どれも一度は通る道なので、知っておくと落ち着いて対処できますよ。

    • OR の付け先を間違える:addOrCondition を付ける相手は、本体の gr そのものでなく、addQuery が返した特定の条件(QueryCondition)です。付け先が変わると、AND と OR のまとまり方も変わります。「どの条件にぶら下げるか」を意識するのが第一歩になります。

    • 数値項目の .0 に驚く:priority のような数値項目では、エンコード文字列が priority=5.0 のように末尾へ .0 を伴うことがあります。これは値の文字列化によるもので、件数には響きません。慌てず、そういうものだと受け止めてください。

    • IN の値の渡し方:IN はカンマ区切りの文字列で候補を渡します。addQuery('priority', 'IN', '1,2') のように、演算子と値の順で書きましょう。数値を素の形で並べず、'1,2' と文字列でくくるのが素直です。

    • 本番でいきなり流す:Scripts - Background のコードは、その場で本番同様に走ります。件数を数える今日のコードは読み取りだけですが、練習は必ず自分の PDI で。ここは毎回きつく念を押しておきます。

    • query() を呼び忘れる:条件をいくら足しても、query() を書かなければ検索は走りません。件数がいつも0のときは、まず query() があるかを見直しましょう。これは①でも触れた、GlideRecord の定番のつまずきです。

    メソッド早見表

    今日出てきたメソッドを、一枚の表に整理しました。まずはこの4つの型を手になじませておけば、AND・OR・IN のたいていの条件は組めます。


    画像

    addQuery は AND の重ね掛けと演算子指定の両方を担い、addOrCondition が OR を、getEncodedQuery が文字列への変換を受け持ちます。役割を一度つかめば、あとは項目名と値を差し替えるだけで応用が利きますよ。

    表の4つは、どれも今日のコードにそのまま出てきたものばかりです。暗記しようと気負わなくても、手を動かして何度か流すうちに、指のほうが先に覚えてくれます。書き方を忘れたら、この表に戻ってくれば大丈夫ですよ。

    今回の実測まとめ

    4つのコードを実機で流した結果を、件数とエンコード文字列で一覧にしました。数字はすべて、Scripts - Background の出力と REST の二重確認を突き合わせたものです。


    画像

    AND が16件、OR が49件、AND の中に OR が20件、IN も同じく20件。OR の49は④の結果と、AND の16は①の結果と、それぞれ別の回の実測ともそろっています。同じ条件は、どの道から数えても同じ数に着く。表を眺めながら、その気持ちよさも味わってください。

    数字が別々の回とそろうのは、偶然ではありません。同じ条件は、文字列で書こうとコードで組もうと、最後は同じ検索に落ち着くからです。だからこそ、①や④の件数と突き合わせる意味があります。もし手元の PDI で近い数が出れば、あなたの組み立ても正しく効いている、という何よりの証しになりますよ。

    まとめ

    条件をコードで組む道具は、今日の4つでほぼ足ります。AND は addQuery を重ねる、OR は addQuery の戻り値に addOrCondition を足す、候補が複数なら addQuery の第2引数に IN を渡す。そして組んだ条件は、getEncodedQuery() でいつでも文字列に直して確かめられます。④の文字列と今日のコードは、向きが違うだけの同じもの。行き来できると分かれば、画面とコードのどちらからでも条件を作れます。それだけです。

    読んで終わりにせず、自分の PDI で同じコードを流してみてください。件数が記事と近い数で返ってきたら、条件の組み立ては手になじんだ証拠。あとは項目名と値を替えるだけで、実務のどんな絞り込みにも応用が利きます。今日のコードは読み取りだけなので、気楽に何度でも試してみてくださいね。

    振り返ると、今日の肝は「どの条件に OR をぶら下げるか」の一点に尽きます。addQuery を重ねれば AND、返ってきた条件に addOrCondition を付ければ OR、候補が多いなら IN。あとは getEncodedQuery で答え合わせをするだけです。この型が手に入れば、たいていの絞り込みは怖くありませんよ。

    次回は、これまで毎回さらりと使ってきた gs(GlideSystem) に光を当てます。gs.info でログを出す、システムプロパティを読む、日時やユーザー情報を取り出す。スクリプトの脇を固めてくれる便利なヘルパーたちを、実機で一つずつ動かしてみる予定です。地味ですが、知っておくと日々のコードがぐっと書きやすくなる回になりますよ。

    その他、実機で確認した記録

    用語

    • addQuery … 条件を1つ足すメソッド。重ねるとすべて AND でつながる

    • addOrCondition … addQuery が返した条件に OR の選択肢を足すメソッド

    • QueryCondition … addQuery の戻り値。この相手に addOrCondition を付ける

    • IN 演算子 … addQuery('項目','IN','1,2') の形で候補を列挙する書き方

    • getEncodedQuery … 組んだ条件を④のエンコード文字列に変換して返す

    • AND / OR … かつ(両方を満たす)/ または(どちらかを満たす)

    実行に使ったスクリプト

    本文の4本のコードは、そのまま Scripts - Background に貼れば動きます(実行は必ず PDI で)。出力はすべて筆者の PDI(dev / Zurich / OOTB)で流した実画面で、件数は REST でも二重に確かめました。

    調べるときの入口URL(先頭に自分のインスタンスを付ける)

    • /sys.scripts.do … Scripts - Background(今回コードを流した画面)

    • /incident_list.do?sysparm_query=active=true^priority=1^ORpriority=2 … AND の中に OR を画面で確認(20件)

    • /incident_list.do?sysparm_query=active=true^priorityIN1,2 … IN で書いた同じ条件を画面で確認(20件)

    • /syslog_list.do?sysparm_query=ORDERBYDESCsys_created_on … System Log(gs.info の出力を辿る)

    実測の要点(再掲)

    • AND … active=true^priority=1 = 16件(①の active 優先度1と一致)

    • OR … priority=1^ORpriority=5.0 = 49件(④の ^OR と一致。.0 は数値項目の文字列化)

    • AND の中に OR … active=true^priority=1^ORpriority=2.0 = 20件(16 + 4)

    • IN … active=true^priorityIN1,2 = 20件(AND の中に OR と同じ数を、短く指定)

    検証範囲とおことわり

    • 実行は PDI(Zurich / OOTB)の Scripts - Background・scope=global のみ。本番やスコープドアプリでの差は範囲外です。

    • ^OR がどこまでを一まとまりに結ぶかの厳密な規則は、実測できた20件という事実にとどめ、断定しません。

    • エンコード文字列の .0 は、priority が10進の数値項目であるための文字列化です。ほかの型では付きません。

    • 件数は執筆時点(確認日 2026-07-19)の値で、インスタンスのデータによって変わります。

    参考リンク

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ