Azure Cosmos DB JavaScript SDK 4.9.3の変更点|ORDER BYと継続トークンの実務対応

Azure Cosmos DB JavaScript SDK を使っているチームが、Azure Cosmos JavaScript SDK 4.9.3 is released で最初に確認すべきことは、ORDER BY と継続トークンを組み合わせたページング処理があるかです。4.9.3は大きなAPI追加ではなく、ORDER BY クエリの継続トークン処理で、バックスラッシュやシングルクォートを含む値が正しく扱われるようにする不具合修正が中心です。管理画面の一覧、検索結果、CSVエクスポート、バッチ集計などで並び替え付きの分割取得をしている場合は、依存関係の更新だけで終わらせず、取得件数・重複・欠落まで確認する必要があります。公式リリースは2026年4月20日に公開され、changelogでは @azure/cosmos 4.9.3 の修正内容として ORDER BY と継続トークンに関するSQLフィルター生成の修正が示されています。(GitHub)

目次

Azure Cosmos DB JavaScript SDK 4.9.3でまず見るべき変更点

Azure Cosmos DB JavaScript SDK 4.9.3の要点は、ORDER BY クエリで継続トークンを使う場合の信頼性改善です。

公式changelogでは、継続トークン内の orderByItem 値をSQLの WHERE 句へ埋め込む前に、バックスラッシュとシングルクォートを適切にエスケープするよう修正されたと説明されています。つまり、画面表示やSDKの使い方が大きく変わる更新ではなく、並び替え付きページングの境界ケースを修正するパッチです。(GitHub)

確認項目内容実務上の見方
対象パッケージ@azure/cosmosNode.js / JavaScript / TypeScriptでCosmos DBを扱うアプリが対象
バージョン4.9.32026年4月20日の修正リリース
変更種別Bugs Fixed新機能追加ではなく不具合修正として扱う
主な修正対象ORDER BY + 継続トークン並び替えながら複数ページで取得する処理を重点確認
関連する値バックスラッシュ、シングルクォートを含む orderByItemWindowsパス、商品コード、名前、外部ID、多言語データで起きやすい
初動コード検索、回帰テスト、段階的ロールアウト依存関係更新だけで終わらせない

この修正は、単に「特殊文字が含まれると例外が出る」タイプの問題ではありません。Pull Requestの説明では、バックスラッシュを含む文字列がCosmos DB SQLパーサーでUnicodeエスケープや制御文字として解釈され、フィルターの不一致によってページング中に行が静かにスキップされ得る、という根本原因が説明されています。(GitHub)

実務では、ここが最も重要です。例外が出れば監視やログで気づけますが、取得結果の一部が抜ける問題は、画面上では正常に見えてしまうことがあります。特に、ページングされた一覧やエクスポート処理では、利用者が「何件あるべきか」を常に把握しているとは限りません。

4.9.xの流れから見ると、継続トークン周りの確認が重要

Azure Cosmos DB JavaScript SDK 4.9.3だけを単発で見るより、4.9.xの流れで捉えると対応方針が立てやすくなります。

バージョン主な変更現場での意味
4.9.0enableQueryControl 使用時のクエリ継続トークン対応クエリのページング制御がより重要になった
4.9.2ストリーミングクエリの継続トークンサイズ肥大化を修正大量取得時のトークン管理に関わる修正
4.9.3ORDER BY クエリと継続トークンのSQLフィルター生成を修正並び替え付きページングの欠落リスクに関わる修正

4.9.xでは、継続トークン、ページング、クエリ実行制御に関する変更が続いています。4.9.3を「小さなパッチ」と見なすのではなく、一覧・検索・エクスポートのデータ品質を確認するタイミングとして扱うのが安全です。(GitHub)

なぜORDER BYと継続トークンの組み合わせが実務で重要なのか

Azure Cosmos DBでは、クエリ結果が大きい場合、結果が複数ページに分割されることがあります。Microsoft Learnでは、結果が1回で返せない場合にCosmos DBが自動的に複数ページへ分割すること、MaxItemCount で1回の要求あたりの最大項目数を指定できること、RU不足・応答サイズ・実行時間・効率上の理由でもページ分割が起きることが説明されています。(Microsoft Learn)

ORDER BY と継続トークンの組み合わせは、次のような処理でよく使われます。

  • 管理画面で作成日時順、名前順、スコア順に一覧表示する
  • 顧客データや注文データをCSVで分割エクスポートする
  • バックエンドAPIで「次のページ」を返す
  • バッチ処理で全件を少しずつ取得して集計する
  • グローバルサービスで多言語の名前、住所、パス、コード値を並び替える

これらの処理では、1ページ目だけ正しく返っても不十分です。2ページ目以降で境界値に特殊文字が含まれると、並び替え条件と継続トークンの扱いが結果の正確性に影響します。

特に注意したいのは、次のような値です。

データ例起こりやすい場所確認すべき理由
O'Reilly氏名、会社名、著者名、ブランド名シングルクォートを含む
C:\Users\adminWindowsパス、ログ出力、ファイル保存先バックスラッシュを含む
Gold\u2013Plan外部システム由来のコード、エスケープ済み文字列Unicodeエスケープ風の文字列に見える
line\nvalueテキスト入力、設定値、メタデータ制御文字風の並びを含む
team\dev's-item部署名、SKU、複合キーバックスラッシュとクォートが混在する

日本語圏のシステムでも、海外ユーザー名、英語の商品名、Windowsパス、外部ID、エスケープ済みJSON文字列を扱う場面では十分に起こり得ます。グローバル向けサービスなら、より優先度を上げて確認すべきです。

影響を受けるコードを最短で洗い出す方法

まずは、@azure/cosmos の利用箇所と、並び替え付きページングの有無を確認します。対象はアプリ本体だけでなく、管理ツール、バッチ、エクスポート用スクリプト、社内APIも含めます。

npm ls @azure/cosmos

pnpmやYarnを使っている場合は、次のように依存関係の解決状況も確認します。

pnpm why @azure/cosmos
yarn why @azure/cosmos

次に、ソースコードからクエリとページング処理を検索します。

rg "ORDER BY|continuationToken|fetchNext|fetchAll|enableQueryControl|maxItemCount" src

見るべきポイントは、単に ORDER BY があるかどうかではありません。次の条件が重なるほど、4.9.3の修正影響を確認する価値が高くなります。

条件優先度理由
ORDER BY と fetchNext() を併用している高ページ単位で結果を処理している可能性が高い
continuationToken を保存・再利用している高APIのページネーションや再開処理に直結する
maxItemCount を小さく設定している高ページ境界が増え、境界ケースを踏みやすい
並び替え対象がユーザー入力や外部データ高クォートやバックスラッシュが混入しやすい
fetchAll() で大量データを取得している中呼び出しは1回に見えても、内部では複数ページになる可能性がある
単一ページで収まる小規模データのみ低影響は限定的だが、将来のデータ増加には注意が必要

生成されたSQL文字列を直接書いていない場合も油断できません。検索条件やソート条件をAPIパラメーターから組み立てている場合、ORDER BY c.name や ORDER BY c.createdAt がヘルパー関数の中で生成されていることがあります。

更新前後で確認すべきテスト観点

4.9.3への更新では、「エラーが出ない」だけでは十分ではありません。確認すべきなのは、全ページを通して、期待したデータが過不足なく取得できるかです。

テスト観点確認方法失敗時に起きること
取得件数期待件数と取得件数を比較する一部の行が抜ける
重複id を Set に入れて重複数を確認する同じ行を複数回処理する
欠落特殊文字を含む固定データを投入して全件取得する特定の値だけ取得されない
並び順前ページ末尾と次ページ先頭の順序を確認するページ境界で順序が乱れる
再開性保存した継続トークンから再開する続きから正しく読めない
空ページresources.length === 0 の扱いを確認する途中で「データなし」と誤判定する

Microsoft LearnのJavaScript SDKドキュメントでは、enableQueryControl を使って継続トークンを扱う例が示されています。また、ORDER BY クエリでは resources や continuationToken が初期呼び出しで空または undefined になることがあり、resources.length > 0 を確認すること、クロスパーティションクエリでは forceQueryPlan: true を使う注意点が説明されています。(Microsoft Learn)

実装例としては、次のように「空ページを即終了扱いにしない」ことが重要です。

const queryIterator = container.items.query(
  "SELECT * FROM c ORDER BY c.sortField",
  {
    maxItemCount: 10,
    enableQueryControl: true,
    forceQueryPlan: true,
  }
);

const ids = new Set<string>();

while (queryIterator.hasMoreResults()) {
  const { resources } = await queryIterator.fetchNext();

  if (resources.length === 0) {
    continue;
  }

  for (const item of resources) {
    ids.add(item.id);
  }
}

テストデータには、通常値だけでなく、次のような値を混ぜてください。JavaScriptの文字列リテラルでは、実データとしてバックスラッシュを1つ入れるために \\ と書く点にも注意します。

const sortFields = [
  "normal",
  "O'Reilly",
  "C:\\Users\\admin",
  "Gold\\u2013Plan",
  "line\\nvalue",
  "team\\dev's-item",
];

このようなデータを投入したうえで、maxItemCount: 1 のようにページ数が増える設定で検証すると、ページ境界の問題を見つけやすくなります。

更新手順は「インストール」より「検証順序」が重要

4.9.3へ明示的に更新する場合、npmでは次のように指定します。

npm install @azure/[email protected]

更新後は、package.jsonだけでなくロックファイルも確認します。

npm ls @azure/cosmos
git diff package.json package-lock.json

pnpmの場合は次のように確認します。

pnpm add @azure/[email protected]
pnpm why @azure/cosmos
git diff package.json pnpm-lock.yaml

実務では、次の順序で進めると事故を減らせます。

手順作業目的
事前調査ORDER BY、continuationToken、fetchNext() の利用箇所を洗い出す影響範囲を限定する
テスト追加特殊文字を含む並び替えデータで回帰テストを作る修正対象に近いケースを再現する
依存関係更新@azure/[email protected] を適用する修正版を取り込む
ステージング確認件数、重複、欠落、順序、空ページ処理を見る正確性を確認する
段階リリース管理画面やバッチなど高影響処理から慎重に反映する本番影響を抑える
監視取得件数、処理件数、エラー、RU、レイテンシを見る更新後の副作用を検知する

ロールバック手段も事前に用意してください。SDK更新は軽く見えますが、Cosmos DBのクエリ結果は業務データそのものです。特に月次レポート、請求関連、監査ログ、顧客向けエクスポートでは、1件の欠落が問い合わせや再処理につながります。

ログと監視で見るべきポイント

4.9.3の確認では、SQL本文や継続トークンをそのままログに出すのは避けるべきです。トークンやクエリ条件には、データ構造や利用者入力に関わる情報が含まれる可能性があります。

代わりに、次のような情報を安全に残すと調査しやすくなります。

ログ項目推奨注意点
SDKバージョン記録するデプロイ単位で確認できるようにする
クエリ種別ORDER BYあり など抽象化して記録する生SQLをそのまま出さない
maxItemCount記録するページ分割の再現に役立つ
ページ番号記録するどのページで異常が出たか追いやすい
取得件数ページごと・合計で記録する欠落や空ページの検知に有効
継続トークン長さやハッシュのみ記録するトークン全文は避ける
RU消費可能なら記録する更新後の性能変化を見る

バッチ処理では、終了時に「処理成功」だけでなく、合計取得件数、ユニークID数、重複数、スキップ数を出すと安全です。画面系では、検索結果の総件数と実際に表示された件数が一致するか、ページ遷移後に同じデータが繰り返し表示されないかを確認します。

すぐ更新すべきケースと、優先度を下げられるケース

4.9.3は不具合修正リリースなので、基本的には更新を検討すべきです。ただし、すべてのシステムで同じ緊急度になるわけではありません。

状況優先度判断理由
ORDER BY と継続トークンを本番APIで使っている高修正対象に直接関係する
CSVエクスポートや帳票出力で大量取得している高欠落が後から発覚しやすい
ユーザー名、住所、パス、外部IDなどを並び替えている高特殊文字が混入しやすい
グローバルユーザー向けサービスで多言語データを扱う高文字種のバリエーションが多い
ORDER BY はあるが常に単一ページで収まる中将来のデータ増加に備えて確認する
Cosmos DBは使うがクエリページングをしていない低直接影響は限定的
旧メジャーバージョンから一気に上げる要調査4.9.3以外の変更も含めて検証が必要

「今のところ問題が見えていない」ことは、必ずしも安全を意味しません。今回の修正は、目に見える例外よりも、結果の正確性に関わる問題として捉えるべきです。

失敗しやすいポイント

package.jsonだけ更新してロックファイルを見ない

CIや本番環境では、ロックファイルに固定されたバージョンが使われます。package.jsonに ^4.9.3 と書いても、lockfileやワークスペースの依存解決によって期待したバージョンにならないことがあります。

更新後は必ず npm ls @azure/cosmos や pnpm why @azure/cosmos で実際の解決結果を確認してください。

1ページ目だけ見て正常と判断する

今回の焦点は、継続トークンを使った2ページ目以降の処理です。1ページ目が正しく表示されても、ページ境界で欠落や重複が起きる可能性があります。

検証では、あえて maxItemCount を小さくしてページ数を増やし、すべてのページを最後まで読み切るテストを行います。

空ページを「検索結果なし」と扱う

enableQueryControl を使う場合、空の応答が返るケースがあります。空ページを見た瞬間に終了すると、後続ページのデータを取り逃がす可能性があります。

resources.length === 0 のときにどう処理するかは、ページング実装の重要な確認点です。

特殊文字を含むテストデータがない

通常の英数字だけでテストしても、4.9.3の修正対象に近いケースは確認できません。最低でも、シングルクォート、バックスラッシュ、Unicodeエスケープ風の文字列、Windowsパス風の文字列を入れてください。

トークン全文をログに残す

継続トークンは再開位置を表す不透明な値です。調査のためにログへ出したくなりますが、全文保存は避けるべきです。ログには有無、長さ、ハッシュ、ページ番号、件数などを残すほうが安全です。

まとめ:4.9.3対応で次にやるべきこと

Azure Cosmos DB JavaScript SDK 4.9.3は、派手な新機能リリースではありません。しかし、ORDER BY と継続トークンを使うページング処理では、取得結果の正確性に関わる重要な修正です。

まず、コードベースから ORDER BY、continuationToken、fetchNext()、fetchAll()、enableQueryControl、maxItemCount を検索してください。次に、バックスラッシュやシングルクォートを含むデータで、件数・重複・欠落・順序を確認する回帰テストを追加します。そのうえで、@azure/[email protected] へ更新し、ステージング環境でページング処理を最後まで検証します。

管理画面、検索API、CSVエクスポート、バッチ集計のように「並び替えながら大量データを読む」処理があるチームでは、今回の更新を単なる依存関係更新ではなく、データ取得ワークフローの品質確認として扱うべきです。最初の一歩は、今すぐ該当クエリを洗い出し、特殊文字を含むページングテストを1つ追加することです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次