Couchbase Lite機能解説：クエリAPI③　演算子


## はじめに

ここでは、Couchbase Lite 3.0の新機能であるクエリ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解説③ 演算子

### 二項演算子

#### 算術演算子

以下が、サポートされています。

`+`(加算)、`-`(減算)、`*`(乗算)、`/`(除算)、`%`(剰余)


`/`(除算)については、両方のオペランドが整数の場合は整数除算が使用され、一方が浮動小数点の場合は浮動小数点除算が使用されます。算術関数`DIV`では、常に浮動小数点除算が実行されます。

#### 比較演算子

一般的に馴染みの深い以下の演算子が、サポートされています。

`=` または `==`(等号)、`!=` また `<>`（不等号）、`>`、`>=`、`<`、`<=`

##### IN

左辺の値が右辺に指定された式にあるかどうかを評価します。
右辺の式として、配列を値として持つプロパティを用いることができます。

```
WHERE “James” IN contactsList
```

##### LIKE

以下の2つのワイルドカードがサポートされています。

- `%`: 0個以上の文字に一致します。
- `_`: 1文字に一致します。

```
WHERE name LIKE ‘a%’
WHERE name LIKE ‘%a’
WHERE name LIKE ‘%or%
WHERE name LIKE ‘a%o%’
WHERE name LIKE ‘%_r%’
WHERE name LIKE ‘%a_%’
WHERE name LIKE ‘%a__%’
```
マッチングは、ASCII文字では大文字と小文字を区別せず、非ASCII文字では大文字と小文字を区別します。

##### MATCH

Couchbase Liteの全文検索機能をクエリで利用するために用います。

```
WHERE <インデックス名> MATCH "value"
```

詳細は、フルテキストサーチ機能に関するドキュメントを参照ください。

https://docs.couchbase.com/couchbase-lite/current/android/fts.html

##### BETWEEN

v1　>= Xおよびv1⇐X+ z

```
WHERE v1 BETWEEN 10 and 100
```

上記は、`WHERE v1 >= 10 AND v1 <= 100 `と同等です。

##### IS (NOT) NULL | MISSING | VALUED

###### IS NULL

nullに等しい

```
WHERE v1 IS NULL
```

###### IS NOT NULL

nullに等しくない

```
WHERE v1 IS NOT NULL
```

###### IS MISSING

MISSINGに等しい(プロパティが定義されていない)

```
WHERE v1 IS MISSING
```

###### IS NOT MISSING

MISSINGに等しくない(プロパティが定義されている)

```
WHERE v1 IS NOT MISSING
```

###### IS VALUED

NULLでも、MISSINGでもない（プロパティが定義されており、null以外の値を持つ）

```
WHERE v1 IS VALUED
```

###### IS NOT VALUED

NULLまたは、MISSING（プロパティが定義されていないか、定義されていても値がnullである）

```
WHERE v1 IS NOT VALUED
```

#### 論理演算子

論理演算子は、ブーリアンとしての評価に、次の論理規則を使用して式を結合します。

- TRUEはTRUE、FALSEはFALSE
- 数字0または0.0はFALSE
- 配列と辞書はFALSE
- 文字列とBlobは、値がゼロ以外としてキャストされる場合はTRUE、値が0または0.0としてキャストされる場合はFALSE
- NULLはFALSE
- MISSINGはMISSING

`TOBOOLEAN`関数を用いる評価では、以下のような違いがあります。

- MISSING、NULLおよびFALSEはFALSE
- 数字0はFALSE
- 空の文字列、配列、およびオブジェクトはFALSE
- 他のすべての値はTRUE

`TOBOOLEAN`関数では、Couchbase ServerのN1QLのルールに基づいて値を変換することができます。

また、以下の論理演算子`AND`、`OR`の評価においても、Couchbase ServerのN1QLとは異なる部分があります。詳細の確認が必要な場合は、ドキュメントを参照ください。

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


##### AND

オペランド式がTRUEと評価された場合、TRUEを返します。それ以外の場合はFALSEを返します。

オペランドがMISSINGで、もう一方がTRUEの場合はMISSINGを返し、もう一方のオペランドがFALSEの場合はFALSEを返します。

一方のオペランドがNULLで、もう一方がTRUEの場合はNULLを返し、もう一方のオペランドがFALSEの場合はFALSEを返します。

```
WHERE city = “San Francisco” AND status = true
```

##### OR

オペランド式の1つがTRUEと評価された場合、TRUEを返します。それ以外の場合はFALSEを返します。

一方のオペランドがMISSINGの場合、他のオペランドがFALSEの場合はMISSINGになり、他のオペランドがTRUEの場合はTRUEになります。

一方のオペランドがNULLの場合、他のオペランドがFALSEの場合はNULLになり、他のオペランドがTRUEの場合はTRUEになります。

```
WHERE city = “San Francisco” OR city = “Santa Clara”
```


##### 文字列演算子

文字列の連結のために`||`を利用することができます。


```
SELECT firstnm || lastnm AS fullname FROM db
```

### 単項演算子

3つの単項演算子`+` `-` `NOT`が提供されています。
`-`は、オペランドを加法における逆言（反数）に置き換えます。`+`は、オペランドを変更しません（正の値であることの強調）。
`NOT`は、ブーリアンの値を反転（TRUEとFALSEを交換する）します。


負の値の表現と正の値の強調の例。

```sql
WHERE v1 >= -10　AND v1 <= +10
```

論理否定演算子利用例。

```sql
WHERE "James" NOT IN contactsList
```

- NOT演算子は、`IN`、`LIKE`、`MATCH`、`BETWEEN`演算子などの演算子と組み合わせて使用​​できます。
- NULL値に対するNOT演算は、NULLを返します。
- MISSING値に対するNOT演算は、MISSINGを返します。


### COLLATE演算子

文字列比較(照合)の実行方法を指定します。文字列比較式およびORDER BY句と組み合わせて使用​​します。

複数の照合を使用する場合は、括弧を用います。照合が1つだけ使用される場合、括弧はオプションです。

Collat​​eはCouchbase ServerのN1QLではサポートされていません

使用可能なオプションは次のとおりです。

- `UNICODE`：Unicode比較を実行する（デフォルトでは、ASCII比較）
- `CASE`: 大文字と小文字を区別して比較を行う
- `DIACRITIC`: アクセントと発音区別符号を考慮に入れる。デフォルトでオン。
- `NO`: 他の照合の接頭辞として使用して、それらを無効にする（`NOCASE`は、大文字と小文字を区別しない）

以下に利用例を示します。

```SQL
SELECT department FROM db WHERE (name = "fred") COLLATE UNICODE
```

```SQL
SELECT department FROM db WHERE (name = "fred") COLLATE (UNICODE)
```

```SQL
SELECT department FROM db WHERE (name = "fred") COLLATE (UNICODE CASE)
```

```SQL
SELECT name FROM db ORDER BY name COLLATE (UNICODE DIACRITIC)
```

### 条件演算子

条件演算子（CASE演算子）は、条件付きロジックを評価します。

シンプルケース（Simple Case）式とサーチドケース（Searched Case）式の両方がサポートされています。構文上の違いは、Simple Case式の場合、CASEキーワードの後に​​式があることです。

- シンプルケース式
 - CASE式が最初のWHEN式と等しい場合、結果はTHEN式になります。
 - それ以外の場合、後続のWHEN句は同じ方法で評価されます。
 - 一致するものが見つからない場合、CASE式の結果はELSE式になり、ELSE式が指定されていない場合はNULLになります。

- サーチドケース式
 - 最初のWHEN式がTRUEの場合、この式の結果はそのTHEN式になります。
 - それ以外の場合、後続のWHEN句は同じ方法で評価されます。 WHEN句がTRUEと評価されない場合、式の結果はELSE式になり、ELSE式が指定されていない場合はNULLになります。



シンプルケース式の例。

```SQL
SELECT CASE state WHEN ‘CA’ THEN ‘Local’ ELSE ‘Non-Local’ END FROM DB
```

サーチドケース式の例。

```SQL
SELECT CASE WHEN shippedOn IS NOT NULL THEN ‘SHIPPED’ ELSE "NOT-SHIPPED" END FROM db
```


### 関連情報

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