クエリの書き方

にメンテナンス済み

kintone の REST API でレコードを複数件取得する際、特定の条件に一致するレコードだけを取得したいケースは非常に多いです。

このような場合に使用するのがクエリ(query)パラメータです。クエリを適切に記述することで、必要なデータだけを効率的に取得できます。

この記事では、kintone のクエリの書き方を基礎から実践まで、豊富なサンプルコードと共に解説します。

クエリの基本構造

クエリは、演算子関数オプションを組み合わせて記述します。

基本的なクエリの構造
const query = 'フィールドコード 演算子 "値" オプション';

例えば、「ステータス」フィールドが「対応中」のレコードを、更新日時の降順で 20 件取得する場合は以下のように記述します。

クエリの記述例
const query = 'ステータス in ("対応中") order by 更新日時 desc limit 20';
フィールドコードについて

クエリで指定するフィールドは、フィールドの「名前」ではなく「フィールドコード」を使用します。 フィールドコードはアプリの設定画面で確認・変更できます。

演算子一覧

演算子は「フィールドコード 演算子 値」の形式で記述します。

比較演算子

演算子説明使用例
=一致するCustomer = "サイボウズ"
!=一致しないStatus != "完了"
>より大きいAmount > 10000
<より小さいCount < 5
>=以上Score >= 80
<=以下Price <= 1000
inいずれかに一致Status in ("対応中", "確認中")
not inいずれにも一致しないCategory not in ("A", "B")

文字列演算子

演算子説明使用例
like含むName like "株式会社"
not like含まないNote not like "キャンセル"
is空であるDetail is empty
is not空でないComment is not empty

論理演算子

演算子説明使用例
andかつ(論理積)Status = "対応中" and Priority = "高"
orまたは(論理和)Status = "完了" or Status = "却下"

フィールドタイプ別の演算子対応表

フィールドの種類によって使用できる演算子が異なります。

フィールドタイプ使用可能な演算子
文字列(1 行)= != in not in like not like
文字列(複数行)like not like is is not
数値= != > < >= <= in not in
日付 / 日時= != > < >= <=
ドロップダウンin not in
チェックボックスin not in
ラジオボタンin not in
ユーザー選択in not in
添付ファイルlike not like is is not
レコード番号= != > < >= <= in not in
選択系フィールドの注意点

ドロップダウン、チェックボックス、ラジオボタンなどの選択系フィールドは、=!= 演算子が使用できません。 必ず in または not in を使用してください。

関数一覧

クエリでは、日付や現在のユーザーを動的に指定できる関数が用意されています。

ユーザー・組織関数

関数説明
LOGINUSER()API を実行したユーザー
PRIMARY_ORGANIZATION()API を実行したユーザーの優先する組織
ログインユーザーが作成したレコードを取得
const query = '作成者 in (LOGINUSER())';

日付・日時関数

関数説明
NOW()API 実行日時
TODAY()API 実行日
YESTERDAY()API 実行日の前日
TOMORROW()API 実行日の翌日
FROM_TODAY(数値, 単位)今日から起算した期間
THIS_WEEK(曜日)今週(曜日指定可能)
LAST_WEEK(曜日)先週
NEXT_WEEK(曜日)来週
THIS_MONTH(日)今月(日付指定可能)
LAST_MONTH(日)先月
NEXT_MONTH(日)来月
THIS_YEAR()今年
LAST_YEAR()昨年
NEXT_YEAR()来年

FROM_TODAY 関数の単位

FROM_TODAY 関数の第 2 引数には以下の単位を指定できます。

単位説明
DAYS日単位
WEEKS週単位
MONTHS月単位
YEARS年単位
過去7日以内に作成されたレコードを取得
const query = '作成日時 >= FROM_TODAY(-7, DAYS)';
今月末が期限のレコードを取得
const query = '期限日 = THIS_MONTH(LAST)';

オプション

クエリの末尾にオプションを追加することで、取得するレコードの並び順や件数を制御できます。

order by(並び替え)

更新日時の降順で取得
const query = 'ステータス in ("対応中") order by 更新日時 desc';
複数フィールドで並び替え
const query = 'order by 優先度 desc, 作成日時 asc';
  • asc: 昇順(小さい順)
  • desc: 降順(大きい順)
  • 省略時はレコード ID の降順

limit(取得件数)

最大20件取得
const query = 'ステータス in ("対応中") limit 20';
  • 0〜500 の範囲で指定可能
  • 省略時は 100 件

offset(スキップ件数)

31件目から取得
const query = 'ステータス in ("対応中") offset 30';
  • 0〜10,000 の範囲で指定可能
  • 省略時は 0
offset の上限に注意

offset の上限は 10,000 件です。10,000 件を超えるレコードを取得する場合は、カーソル API の使用を検討してください。

実践的なサンプルクエリ

基本的な絞り込み

完全一致で絞り込み
const query = '顧客名 = "サイボウズ株式会社"';
部分一致で絞り込み
const query = '顧客名 like "株式会社"';
複数の値のいずれかに一致
const query = 'ステータス in ("対応中", "確認中", "保留")';

日付による絞り込み

今日が期限のタスク
const query = '期限日 = TODAY()';
期限切れのタスク(未完了)
const query = '期限日 < TODAY() and ステータス not in ("完了")';
今週中に対応が必要なタスク
const query = '期限日 >= TODAY() and 期限日 <= THIS_WEEK(SUNDAY)';
日付範囲の指定
const query = '作成日時 >= "2024-01-01" and 作成日時 <= "2024-12-31"';

複合条件

優先度が高く未完了のタスク(更新日時順)
const query = '優先度 in ("高") and ステータス not in ("完了") order by 更新日時 desc';
グループ化による複雑な条件
// 「緊急」または「期限切れかつ未完了」のタスク
const query = '(優先度 in ("緊急")) or (期限日 < TODAY() and ステータス not in ("完了"))';

ユーザーによる絞り込み

自分が担当のレコード
const query = '担当者 in (LOGINUSER())';
自分が作成したレコード
const query = '作成者 in (LOGINUSER())';

空欄チェック

コメントが空のレコード
const query = 'コメント is empty';
添付ファイルがあるレコード
const query = '添付ファイル is not empty';

JavaScript での実装例

基本的な使用方法

クエリを使用したレコード取得
(() => {
  'use strict';

  /**
   * 条件に一致するレコードを取得する
   * @param {string} query - 検索条件
   * @returns {Promise<object[]>} レコードの配列
   */
  const fetchRecords = async (query) => {
    const appId = kintone.app.getId();
    const response = await kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', {
      app: appId,
      query,
    });
    return response.records;
  };

  kintone.events.on(['app.record.index.show'], async (event) => {
    // 今日が期限の未完了タスクを取得
    const query = '期限日 = TODAY() and ステータス not in ("完了") order by 優先度 desc';
    const records = await fetchRecords(query);

    console.log(`本日期限のタスク: ${records.length}件`);
    records.forEach((record) => {
      console.log(`- ${record['タスク名'].value}`);
    });

    return event;
  });
})();

動的なクエリの構築

条件を動的に組み立てる
(() => {
  'use strict';

  /**
   * 条件を動的に組み立ててクエリ文字列を生成する
   * @param {object} filters - フィルター条件
   * @returns {string} クエリ文字列
   */
  const buildQuery = (filters) => {
    const conditions = [];

    if (filters.status && filters.status.length > 0) {
      const statusList = filters.status.map((s) => `"${s}"`).join(', ');
      conditions.push(`ステータス in (${statusList})`);
    }

    if (filters.assignee) {
      conditions.push(`担当者 in ("${filters.assignee}")`);
    }

    if (filters.startDate) {
      conditions.push(`作成日時 >= "${filters.startDate}"`);
    }

    if (filters.endDate) {
      conditions.push(`作成日時 <= "${filters.endDate}"`);
    }

    let query = conditions.length > 0 ? conditions.join(' and ') : '';

    if (filters.orderBy) {
      query += ` order by ${filters.orderBy}`;
    }

    if (filters.limit) {
      query += ` limit ${filters.limit}`;
    }

    return query;
  };

  // 使用例
  const filters = {
    status: ['対応中', '確認中'],
    startDate: '2024-01-01',
    orderBy: '更新日時 desc',
    limit: 50,
  };

  const query = buildQuery(filters);
  console.log(query);
  // 出力: ステータス in ("対応中", "確認中") and 作成日時 >= "2024-01-01" order by 更新日時 desc limit 50
})();

エスケープ処理

クエリの値にダブルクォートやバックスラッシュが含まれる場合は、エスケープが必要です。

特殊文字のエスケープ
/**
 * クエリ値をエスケープする
 * @param {string} value - エスケープする値
 * @returns {string} エスケープ後の値
 */
const escapeQueryValue = (value) => {
  return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
};

// 使用例
const customerName = 'サイボウズ "株式会社"';
const escapedName = escapeQueryValue(customerName);
const query = `顧客名 = "${escapedName}"`;
// 結果: 顧客名 = "サイボウズ \"株式会社\""

テーブル(サブテーブル)内フィールドの検索

テーブル内のフィールドを検索する場合、=!= 演算子は使用できません。代わりに innot in を使用します。

テーブル内の日時フィールドを検索
// テーブル内の「対応日時」フィールドが特定の日時
const query = '対応日時 in ("2024-11-28T05:00:00Z")';
日時の形式に注意

テーブル内の日時フィールドを検索する場合、ISO 8601 形式(UTC)で指定する必要があります。

レコード番号($id)での検索

レコード番号フィールドは、フィールドコードの代わりに $id システム識別子で指定できます。

レコード番号で絞り込み
const query = '$id >= 100 and $id <= 200';
特定のレコード番号を除外
const query = '$id not in (1, 2, 3)';

よくあるエラーと対処法

「不正なクエリです」エラー

よくある原因と対処法:

  1. フィールドコードの誤り: フィールド名ではなくフィールドコードを使用しているか確認
  2. 演算子の不一致: フィールドタイプに対応した演算子を使用しているか確認
  3. 引用符の不足: 文字列値は必ずダブルクォートで囲む
  4. エスケープ漏れ: 特殊文字が含まれる場合はエスケープ処理を行う
よくある間違い
// ❌ 選択系フィールドに = を使用
const query = 'ステータス = "対応中"';

// ✅ 選択系フィールドには in を使用
const query = 'ステータス in ("対応中")';
よくある間違い
// ❌ 文字列値を引用符で囲んでいない
const query = '顧客名 = サイボウズ';

// ✅ 文字列値はダブルクォートで囲む
const query = '顧客名 = "サイボウズ"';

まとめ

kintone のクエリを適切に使用することで、必要なデータだけを効率的に取得できます。

ポイントをまとめると:

  • フィールドコードを正確に指定する
  • フィールドタイプに応じた演算子を使用する
  • 日付関数を活用して動的な条件を設定する
  • 複雑な条件は括弧でグループ化する
  • 特殊文字は適切にエスケープする

これらを押さえておくことで、kintone REST API をより効果的に活用できるようになります。

関連ページ

レコードの取得(複数件)
kintone REST APIを使用して、レコードを複数件取得する方法を紹介します。レコードIDを指定して、レコード情報を取得することができます。
POST, PUT, DELETEの上限
kintone REST APIには、GET, POST, PUT, DELETEそれぞれに、1度に操作できるレコードの上限が設けられています。今回は上記のレコード上限を気にすることなく、一括でレコードの作成ができる関数をご紹介します。RE

練習問題

ドロップダウンフィールド「カテゴリ」の値が「営業」または「開発」のレコードを取得するクエリとして正しいものはどれですか?

ドロップダウンフィールドには = 演算子は使用できません。選択系フィールド(ドロップダウン、チェックボックス、ラジオボタンなど)には in または not in 演算子を使用します。

過去30日以内に作成されたレコードを取得するクエリとして正しいものはどれですか?

FROM_TODAY(数値, 単位) 関数を使用して、今日を基準とした期間を指定できます。 負の数値を指定すると過去の日付を、正の数値を指定すると未来の日付を表します。 between 演算子は kintone のクエリでは使用できません。

#kintone #JavaScript #TypeScript #REST API