DocumentDBで集計関数を使う

Planet scale aggregates with Azure DocumentDBでアナウンスがあった通り、DocumentDBで集計関数が使えるようになりました。

DocumentDBはNoSQLでありながらSQL文が使えるという特長があっただけに、集計関数が使えなかったことが逆に目立ってしまっていました。私も関わっているプロジェクト関係者の方に「集計関数使えないんですか〜」と何回も聞かれた記憶があります。

しかし、これで集計関数が利用できるようになったので、DocumentDBを使ったデータハンドリングの幅が広がることは間違いなさそうです。

使える集計関数

利用できる集計関数は現在のところ以下の5つですが、最低限これで十分でしょう。

  • COUNT: 式の項目の数
  • SUM: 式のすべての値の合計
  • MIN: 式の最小値
  • MAX: 式の最大値
  • AVG: 式の値の平均

SQLクエリでの使い方

SQL文での書き方は、標準SQLとあまり変わりません。例えば、priceというカラムの合計を算出するクエリは以下のように記述できます。

SELECT sum(i.price) as totalPrice FROM items as i
{
"totalPrice": 28000
}

基本的にはRDBMSに対するSQLクエリとほぼ同じように書けます。
ただし、件数カウントについては、以下のように*count()ではなくcount(1)**と書かなければならないようです。

SELECT count(1) as totalNumber FROM Items as c
{
"totalNumber": 7
}

ちなみにAzureポータルでは、DocumentDBのクエリエクスプローラーからSQLクエリをサクッと試すことができます。開発中にちょっとデータを確認したいという時にはとても便利な機能ですね。

クエリエクスプローラー

ただし、クエリエクスプローラーで集計関数を試す場合には、1ページの最大表示件数制限が設定されていると、期待された値にならない場合があります。全件を対象にして集計する場合などは、クエリの設定で1ページあたりのアイテム数を無制限に設定する必要がありますのでご注意を。

.NET SDKでの使い方

私は、実際にプロダクトにDocumentDBの処理を組み込む際に、生SQLを書くことはあまりなく、結局.NET SDKを使ってLINQで書くことがほとんどになります。

SDK経由でも集計関数が使えるようになったので、以下はその例です。なお、集計関数に対応しているSDKのバージョンは、1.12.0以降になりますので、必要に応じてNugetを更新しておきましょう。

Microsoft.Azure.Documents.Linqをusingすると、以下の集計関数を使えるようになります。

  • CountAsync()
  • SumAsync()
  • AverageAsync()
  • MinAsync()
  • MaxAsync()

CountAsync以外は、先に集計対象のカラムをSelect()しておく必要があります。従来のLINQのSum(c => c.Price)みたいな書き方ではない点に注意が必要です。