はじめに
ここでは、Couchbase Lite 3.0の新機能であるクエリAPIについて解説します。
なお、Couchbase Mobileについては、Couchbase Mobileアプリケーション開発へのロードマップに記事をまとめている他、(これらの記事を元に構成した)以下の電子書籍を無償で頒布しています。
また、Couchbase Mobileは、Couchbase LiteとCouchbase Serverとのデータ同期機能を提供します。Couchbase Serverの存在意義、機能詳細、利用方法等については、拙著NoSQLドキュメント指向データベースCouchbase Serverファーストステップガイド(インプレスR&D刊)や、NoSQL/JSONデータベースCouchbase Server理解・活用へのロードマップにまとめてある記事をご参考ください。
概要
Couchbase Liteを利用する開発者は、SQL類似のクエリを使用して、データベースを検索することができます。クエリAPIは、次に示す形式のクエリステートメントを使用します。
SELECT ____
FROM ____
WHERE ____,
JOIN ____
GROUP BY ____
ORDER BY ____
それぞれのキーワードについて、以下簡単に記します。これらは、SQL経験者には馴染み深いものだと思います。
-
SELECT
ステートメントには、結果セットとして返されるドキュメントプロパティを指定します -
FROM
には、ドキュメントを照会するデータベースを指定します -
WHERE
ステートメントでは、ドキュメントの検索条件を指定します。 -
JOIN
ステートメントは、複数のドキュメントを結合するための条件を指定します。 -
GROUP BY
ステートメントは、結果セットとして返されるアイテムをグループ化するために使用される基準を指定します。 -
ORDER BY
ステートメントは、結果セット内のアイテムの順序付けに使用される基準を指定します。
このように、クエリ形式の構造とセマンティクスは、SQLに基づきます。さらに、SQLには含まれていないJSONデータの操作に関する部分は、Couchbase Serverと同じく、SQL++に基づいています。
SQL++
SQL++は、カリフォルニア大学で生み出され、Apache AsterixDBでも採用されています。
SQL++の提唱者Yannis Papakonstantinou等による論文「The SQL++ Query Language: Configurable, Unifying and Semi-structured」では、N1QLについて「syntactic sugar over SQL++」という表現が用いられています。
N1QL
N1QLという名前は、リレーショナルデータモデルにおける第一正規型(first normal form)と関係し、非第一正規型クエリ言語(Non 1st normal form Query Language)の略称であり、ニッケルと発音します。
N1QLは、Couchbase固有の名称ですが、その設計は、SQL++に由来します。
定義と実行
Database
クラスのcreateQuery
メソッドを使用して、クエリ文字列からQuery
オブジェクトを作成します。
Query
オブジェクトのexecute
メソッドを使用してクエリを実行します。
下記コード中の、db
は、生成・初期化済みのDatabase
オブジェクトです。
Query thisQuery = db.createQuery(
"SELECT META().id AS thisId FROM _ WHERE type = \"hotel\"");
return thisQuery.execute().allResults();
val thisQuery = db.createQuery(
"SELECT META().id AS id FROM _ WHERE type = \"hotel\"")
return thisQuery.execute().allResults()
なお、ここでは、省略表記_
を使用して現在のデータベースにアクセスしています。
構成要素
SELECT
SELECT句はSELECT
キーワードで始まります。
-
SELECT ALL ...
は、すべての結果を返します(ALL
は、デフォルトであり、記載不要) -
SELECT DISTINCT ...
は、重複した結果を削除します。
上記の...
の箇所には、JSONドキュメントのプロパティを指定します。AS
引数を使用して、プロパティにエイリアス名を指定することができます。また、ワイルドカード*
を使用して、すべての列を指定できます。
FROM
データソースを指定します。オプションとして、エイリアス(AS
)を適用することができます。
名前を指定せずに現在のデータベースを使用するには_
をデータソースとしてを使用します。
以下の例を参照ください。
SELECT name FROM db
SELECT store.name FROM db AS store
SELECT store.name FROM db store
SELECT name FROM _
SELECT store.name FROM _ AS store
SELECT store.name FROM _ store
JOIN
指定された基準によってリンクされた複数のデータソースからデータを選択できます。
Couchbase Liteのデータソースはデータベース (ファイル)そのものであり、データベース(ファイル)間の結合はサポートされていないため、JOIN句は、自己結合のために利用されます。
JOIN句は、JOIN演算子で始まり、その後にデータソースが続きます。
次の5つのJOIN演算子がサポートされています:JOIN
、LEFT JOIN
、LEFT OUTER JOIN
、INNER JOIN
、CROSS JOIN
なお、JOIN
とINNER JOIN
は同義であり、LEFT JOIN
とLEFT OUTER JOIN
は同義です。
結合制約は、ON
キーワードで始まり、その後に結合制約を定義する式が続きます。
たとえば、次の例を参照してください。
ここでは、航空会社の詳細を、航空会社IDでリンクされたルートの詳細と組み合わせています。
SELECT db.prop1, other.prop2 FROM db JOIN db AS other ON db.key = other.key
SELECT db.prop1, other.prop2 FROM db LEFT JOIN db other ON db.key = other.key
SELECT * FROM travel-sample r JOIN travel-sample a ON r.airlineid = a.meta.id WHERE a.country = "France"
次の例では、_airline
ドキュメントとルートドキュメントのドキュメントID(airlineid
)を使用して、route
タイプのドキュメントをairline
タイプのドキュメントと結合しています。
SELECT * FROM travel-sample r JOIN travel-sample a ON r.airlineid = a.meta.id WHERE a.country = "France"
WHERE
クエリによって返されるドキュメントの選択基準を指定します。
BOOLEAN値に評価される任意の数の式をチェーンできます。
次の例を参照ください。
SELECT name FROM db WHERE department = ‘engineer’ AND group = ‘mobile'
GROUP BY
クエリ結果をグループ化します。
通常、集計関数(COUNT
、MAX
、MIN
、SUM
、AVG
など)と一緒に使用されます。
オプションとして、HAVING
句を使って、集計関数に基づいて結果をフィルタリングできます(例えば、HAVING count(empnum)>100
のように)。
次の例を参照ください。
SELECT COUNT(empno), city FROM db GROUP BY city
SELECT COUNT(empno), city FROM db GROUP BY city HAVING COUNT(empno) > 100
SELECT COUNT(empno), city FROM db GROUP BY city HAVING COUNT(empno) > 100 WHERE state = ‘CA’
ORDER BY
クエリ結果を並べ替えます。
オプションのASC
(昇順)またはDESC
(降順)を使用して並べ替え方向を指定します。デフォルトはASC
です。
次の例を参照ください。
SELECT name FROM db ORDER BY name
SELECT name FROM db ORDER BY name DESC
SELECT name, score FROM db ORDER BY name ASC, score DESC
LIMIT
クエリによって返される結果の最大数を指定します。
次の例は、10件の結果のみを返します。
SELECT name FROM db LIMIT 10
OFFSET
クエリの結果をスキップする数を指定します。
次の例は、最初の10件の結果を無視して、残りの結果を返します。
SELECT name FROM db OFFSET 10
次の例は、最初の10件の結果を無視してから、次の10件の結果を返します。
SELECT name FROM db LIMIT 10 OFFSET 10
関連情報