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/cosmos | Node.js / JavaScript / TypeScriptでCosmos DBを扱うアプリが対象 |
| バージョン | 4.9.3 | 2026年4月20日の修正リリース |
| 変更種別 | Bugs Fixed | 新機能追加ではなく不具合修正として扱う |
| 主な修正対象 | ORDER BY + 継続トークン | 並び替えながら複数ページで取得する処理を重点確認 |
| 関連する値 | バックスラッシュ、シングルクォートを含む orderByItem | Windowsパス、商品コード、名前、外部ID、多言語データで起きやすい |
| 初動 | コード検索、回帰テスト、段階的ロールアウト | 依存関係更新だけで終わらせない |
この修正は、単に「特殊文字が含まれると例外が出る」タイプの問題ではありません。Pull Requestの説明では、バックスラッシュを含む文字列がCosmos DB SQLパーサーでUnicodeエスケープや制御文字として解釈され、フィルターの不一致によってページング中に行が静かにスキップされ得る、という根本原因が説明されています。(GitHub)
実務では、ここが最も重要です。例外が出れば監視やログで気づけますが、取得結果の一部が抜ける問題は、画面上では正常に見えてしまうことがあります。特に、ページングされた一覧やエクスポート処理では、利用者が「何件あるべきか」を常に把握しているとは限りません。
4.9.xの流れから見ると、継続トークン周りの確認が重要
Azure Cosmos DB JavaScript SDK 4.9.3だけを単発で見るより、4.9.xの流れで捉えると対応方針が立てやすくなります。
| バージョン | 主な変更 | 現場での意味 |
|---|---|---|
| 4.9.0 | enableQueryControl 使用時のクエリ継続トークン対応 | クエリのページング制御がより重要になった |
| 4.9.2 | ストリーミングクエリの継続トークンサイズ肥大化を修正 | 大量取得時のトークン管理に関わる修正 |
| 4.9.3 | ORDER 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\admin | Windowsパス、ログ出力、ファイル保存先 | バックスラッシュを含む |
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つ追加することです。

コメント