cosmosdb-query-builderというnpmパッケージを作った

www.npmjs.com

node用DocumentDBのライブラリと組み合わせて使うことを想定しています。

動機とか

Win機が手元になくても大丈夫だったり、Lambda と同じノリで書けたりという理由で Azure Functions での開発にはもっぱら node を選択しているのですが、

  1. ありがちな動的に where 句の構成条件が変わるような要件を、文字列操作しまくってなんとかするのは(開発時はよくてもメンテが)なかなかストレスフル
  2. せっかく SQL(的記法)が使えるんならORMまではいかずともクエリビルダーが欲しくなってきた
  3. ざっと探してもなさそうなので、どうせならさいくろん先輩の馴染みのアレみたいな書き方をしたい

というわけで作りました。
そもそも日本で Azure Functions を、しかも Node.js でやっていき人口はだいぶ少ないと思うのですが*1、ありがたいことに多少は npm i されてるっぽいので、必要な人に届いたらいいなあと思います。

DocumentDB は他の RDBMS 達と違って以下のようなしんどめの diff があります:

  • 単一コレクション(テーブル)のクエリでもカラムにコレクション名をつけないといけない
  • LIMIT 句は SELECT とカラムの間に指定する(!?)

主にこの2点と、あとは値のバインドの形が若干煩わしいので、主にそのあたりを解消することを目的としています。

つかいかた/できること

Inspired by CPAN module なので SYNOPSIS とかついてます。

const querySpec = builder.query(
  'SELECT %l %c FROM %t WHERE %w %o',
  20,
  ['id', 'age'],
  'c',
  { id: 200 },
  {
    order: {
      sort: 'desc',
      key: 'createdAt'
    }
  }
);
// SELECT TOP @_top c.id, c.age FROM c WHERE ( c.id = @id ) ORDER BY c.createdAt desc

LIMIT 句を表現するのに、本家のように %o のようなキーワードで吸収できたらいいんですがなかなか…。
また前述の理由で引数にコレクション名を取ります。一応 %t 記法もサポートしたけど今のところあんまり意味ない。

WHERE 句は operator 指定できたり AND/OR のネストができたり関数指定ができたりします。
あとは DocumentDB はストアしている json の型にはめちゃんこ厳しいので、対応するために type 句を取ったりしてます(string 型はちゃんとクオートしないと引けない)。
というわけで地味に便利な仕上がりになっていると思います。

できないこと

現状 JOIN, GROUP 系の記法には対応していません。PRお待ちしてます!

*1:しかし Azure Functions + CosmosDB はベーシックなユースケースでは Lambda + Dynamo より楽で安いと思う。中小企業の味方!なんとベータ版ならNode10も使える!