Couchbase Lite機能解説：クエリAPI④関数


## はじめに

ここでは、Couchbase Lite 3.0の新機能であるSQL++/N1QLクエリAPIについて解説します。

なお、Couchbase Mobileについては、[Couchbase Mobileアプリケーション開発へのロードマップ](https://qiita.com/yoshiyuki_kono/items/6a5bbad1b02196a25417)に記事をまとめている他、（これらの記事を元に構成した）以下の電子書籍を無償で頒布しています。

https://techbookfest.org/product/5074954942939136?productVariantID=5042865933647872

また、Couchbase Mobileは、Couchbase LiteとCouchbase Serverとのデータ同期機能を提供します。Couchbase Serverの存在意義、機能詳細、利用方法等については、拙著[NoSQLドキュメント指向データベースCouchbase Serverファーストステップガイド(インプレスR&D刊)](https://www.amazon.co.jp/-/en/%E6%B2%B3%E9%87%8E-%E6%B3%B0%E5%B9%B8/dp/429560030X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1636588872&sr=1-1)や、[NoSQL/JSONデータベースCouchbase Server理解・活用へのロードマップ](https://qiita.com/yoshiyuki_kono/items/4c9cd1115efc5807b49f)にまとめてある記事をご参考ください。

## クエリAPI④関数

SQL++/N1QLクエリで利用できる関数を、Couchbase Liteに固有の機能を中心に紹介します。


### メタデータ関数 (META)


メタデータ関数 (META)を用いて、次のようなドキュメントのメタデータを取得することができます。

この関数は、次のようなプロパティを含むディクショナリを返します。

- `id`：ドキュメント識別子
- `sequence`：ドキュメント変更シーケンス番号
- `deleted`：ドキュメントが削除されたかどうかを示すフラグ
- `expiration`：タイムスタンプ形式のドキュメントの有効期限

利用例を示します。

```sql
SELECT META() FROM db

SELECT META().id, META().sequence, META().deleted, META().expiration FROM db
```

上記のようなシンプルなクエリの場合は不要ですが、`META(<データソース名>)`のように、データソース名を引数に指定することによって、メタデータを取得する対象を識別することが可能です。これは、下記のような結合を行っているクエリで、利用することができます。この、<データソース名>には、データベース名またはエイリアス名を利用できます。

```sql
SELECT p.name, r.rating FROM product as p INNER JOIN reviews AS r ON META(r).id IN p.reviewList WHERE META(p).id = "product320"
```

### 全文検索(FTS)関数

#### MATCH

`MATCH(<FTSインデックス名>, <検索語>)`は、検索語が、指定されたFTSインデックスに含まれる場合にTRUEを返します。

`WHERE MATCH (description_index, “couchbase”)`

#### RANK

`RANK`は、インデックス名を引数として取ります。
MATCH関数とともに用いて、クエリの結果がFTSインデックスとどの程度一致しているかを示す数値を返します。
以下のように用いることができます。

```
WHERE MATCH (<インデックス名>, <検索語>) ORDER BY RANK(<インデックス名>)
```



### 配列関数

入力として配列を受け取る関数です。

| 関数 | 説明 | 
|:-----------|:------------|
|ARRAY_AGG(expr)|NULL値を含む、入力式のMISSING以外のグループ値の配列を返します。|
|ARRAY_AVG(expr)|配列内のすべてのNULL以外の数値の平均を返します。ない場合はNULL|
|ARRAY_CONTAINS(expr)|値が配列に存在する場合はTRUEを返します。それ以外の場合はFALSEを返します。|
|ARRAY_COUNT(expr)|配列内のNULL以外の値の数を返します|
|ARRAY_IFNULL(expr)|配列内のNULL以外の最初の値を返します|
|ARRAY_MAX(expr)|配列内の最大の値を返します。NULLとMISSINGは無視されます。|
|ARRAY_MIN(expr)|配列内の最小の値を返します。NULLとMISSINGは無視されます。|
|ARRAY_LENGTH(expr)|配列の長さを返します|
|ARRAY_SUM(expr)|配列内のすべてのNULL以外の数値の合計を返します|

### 条件関数

| 関数 | 説明 | 
|:-----------|:------------|
|IFMISSING(expr1, expr2, …​)|MISSING以外の最初の値を返します。すべての値がMISSINGの場合はNULLを返します。|
|IFMISSINGORNULL(expr1, expr2, …​)|非NULLおよび非MISSINGである最初の値を返します。すべての値がNULLまたはMISSINGの場合はNULLを返します。|
|IFNULL(expr1, expr2, …​)|最初の非NULL値を返します。すべての値がNULLの場合はNULLを返します|
|MISSINGIF(expr1, expr2)|expr1 = expr2の場合にMISSINGを返します。それ以外の場合はexpr1を返します。いずれかまたは両方の式がMISSINGにMISSINGを返します。いずれかまたは両方の式がNULLの場合には、NULLを返します。|
|NULLF(expr1, expr2)|expr1 = expr2の場合にNULLを返します。それ以外の場合はexpr1を返します。いずれかまたは両方の式がMISSINGの場合にMISSINGを返します。いずれかまたは両方の式がNULLの場合には、NULLを返します。|

### スカラ関数

スカラ関数は、入力するひとつの値に対し、ひとつの結果を返す関数です。

#### 日付時間関数
| 関数 | 説明 | 
|:-----------|:------------|
|STR_TO_MILLIS(expr)|ISO 8601形式の文字列を、UNIXエポック（ミリ秒）に変換します。
|STR_TO_UTC(expr)|ISO 8601形式の文字列を、UTCのISO 8601形式の文字列に変換します。
|MILLIS_TO_STR(expr)|UNIXエポック（ミリ秒）をローカルタイムゾーンのISO 8601形式の文字列に変換します。
|MILLIS_TO_UTC(expr)|UNIXエポック（ミリ秒）をUTCのISO 8601形式の文字列に変換します。


UNIXエポック (Unix epoch）とは、UNIX OSにおいて利用される日時の表現であり、具体的には「1970年1月1日午前0時0分0秒（UTC）」を基準として、そこから経過した秒数で日時を表現します。

#### 算術関数

下記のような算術関数が提供されています。詳細は、ドキュメントを参照ください。

`ABS` `ACOS` `ASIN` `ATAN` `ATAN2` `CEIL` `COS` `DIV` `DEGREES` `E` `EXP` `FLOOR` `LN` `LOG` `PI` `POWER` `RADIANS` `ROUND` `ROUND_EVEN` `SIGN` `SIN` `SQRT` `TAN` `TRUNC`


#### 文字列関数

下記のような文字列関数が提供されています。詳細は、ドキュメントを参照ください。

`CONTAINS` `LENGTH` `LOWER` `LTRIM` `RTRIM` `TRIM` `UPPER`

### 集計関数

集計関数は、入力となる集合に対し、ひとつの結果を返す関数です。下記の関数が利用可能です。

`AVG`(平均値) `COUNT`(データ数) `MIN`(最小値) `MAX`(最大値) `SUM`(合計値)


### パターン検索関数

| 関数 | 説明 | 
|:-----------|:------------|
|REGEXP_CONTAINS(expr, pattern)|文字列に正規表現パターンに一致するシーケンスが含まれている場合はTRUEを返します。
|REGEXP_LIKE(expr, pattern)|文字列が正規表現パターンと完全に一致する場合はTRUEを返します。
|REGEXP_POSITION(expr, pattern)|文字列中の正規表現パターンの出現する最初の位置を返します。一致するものが見つからない場合は-1を返します。位置のカウントはゼロから始まります。
|REGEXP_REPLACE(expr, pattern, repl [, n])|`pattern`が`repl`に置き換えられた新しい文字列を返します。nを指定すると、最大n個の置換が実行されます。nが指定されていない場合、一致するすべてのオカレンスが置き換えられます。



### データ型チェック関数

SQL++/N1QLでは、ブーリアン評価において、結果は、TRUEとFALSE以外にNULLやMISSINGを取ることがあります。データ型チェック関数が評価する値がNULL、またはMISSINGの場合は、ブーリアン型への評価が行われず、そのままNULLまたはMISSINGが返されます。

| 関数 | 説明 | 
|:-----------|:------------|
|ISARRAY(expr)|式が配列の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|ISATOM(expr)|式がブール値、数値、または文字列の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|ISBOOLEAN(expr)|式がブール値の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|ISNUMBER(expr)|式が数値の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|ISOBJECT(expr)|式がオブジェクト（ディクショナリ）の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|ISSTRING(expr)|式が文字列の場合はTRUEを返し、それ以外の場合はMISSING、NULL、またはFALSEを返します。
|TYPE(expr)|式の値に基づいて、次のいずれかの文字列を返しす：`“missing”`,`“null”`,`“boolean”`,`“number”`,`“string”`,`“array”`,`“object”`,`“binary”`

### データ型変換関数


| 関数 | 説明 | 
|:-----------|:------------|
|TOARRAY(expr)|配列自体を返します。または、配列にラップされた値を返します。|
|TOATOM(expr)|値が配列の場合、単一の項目の配列を返します。値がオブジェクトの場合、単一のキーと値のペアのオブジェクトを返します。ブール値、数値、または文字列を返します他のすべての値についてはNULLを返します。
|TOBOOLEAN(expr)|値がFALSEの場合、FALSEを返します。値が0またはNaNの場合、FALSEを返します。値が空の文字列、配列、およびオブジェクトの場合はFALSEを返します。他のすべての値についてはTRUEを返します。
|TONUMBER(expr)|値がFALSEの場合は0を返します。値がTRUEの場合は1を返します。値がNUMBERの場合、NUMBERを返します。文字列値から解析されたNUMBERを返します。他のすべての値についてはNULLを返します。
|TOOBJECT(expr)|値がオブジェクトの場合、オブジェクトを返します。他のすべての値に対して空のオブジェクトを返します。
|TOSTRING(expr)|値がFALSEの場合、「false」を返します。値がTRUEの場合、「true」を返します。値がNUMBERの場合、文字列でNUMBERを返します。値が文字列の場合、文字列値を返します。他のすべての値についてはNULLを返します。|



### 関連情報

https://docs.couchbase.com/couchbase-lite/current/android/query-n1ql-mobile.html#lbl-functions



http://wisdom.sakura.ne.jp/database/sql/sql9.html

http://www.sql-post.biz/2019/05/02/%E6%A8%99%E6%BA%96sql/