Neo4j Cypherマニュアルv4.4 2:構文

# 構文
:::note info
本章では、問い合わせ言語Cypherの構文を説明します。
:::

## 値と型
:::note info
本節では、Cypherのデータ型の概要を説明します。
:::

Cypherは、多くのデータ型を非常によくサポートしています。
これらはいくつかのカテゴリに分類され、以下の小節で詳細に説明しています。
<dl>
  <dt>プロパティ型</dt>
  <dd>Integer, Float, String, Boolean, Point, Date, Time, LocalTime, DateTime, LocalDateTime, Duration</dd>
  <dt>構造型</dt>
  <dd>Node, Relationship, Path</dd>
  <dt>複合型</dt>
  <dd>List, Map</dd>
</dl>

### 1. プロパティ型
* Cypherクエリから返すことができます。
* パラメータとして使用可能です。
* プロパティとして保存可能です。
* Cypherリテラルを使って構築可能です。

プロパティの種類は以下の通りです。
* __Number__
抽象的な型であり、__Integer__ と __Float__ のサブタイプを持ちます。
* __String__
* __Boolean__
* __Point__
空間型です。
* __Date__, __Time__, __LocalTime__, __DateTime__, __LocalDateTime__, __Duration__
時間型です。


形容詞の _numeric_ は、Cypherの関数や式を説明する文脈で使用される場合、任意の型の数（IntegerでもFloatでも）を適用できることを表します。

単純な型の同種のリストもプロパティとして保存できますが、一般的なリスト（[複合型](https://neo4j.com/docs/cypher-manual/current/syntax/values/#composite-types)を参照）は保存できません。

Cypherはまた、バイト配列のパススルーサポートを提供しており、プロパティ値として保存することができます。バイト配列は Cypherでは優れたデータ型とは見なされていないため、リテラル表現を持ちません。

:::note
__特殊文字のソートについて__
[Basic Multilingual Plane (BMP)](https://ja.wikipedia.org/wiki/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2#:~:text=%E5%9F%BA%E6%9C%AC%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2%EF%BC%88%E3%81%8D,%E3%81%AE%E3%81%BB%E3%81%A8%E3%82%93%E3%81%A9%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%82%8B%E3%80%82) に属さない文字を含む文字列は、Neo4jでは一貫性のない、あるいは非決定的な順序になることがあります。BMPは、Unicodeで定義された全ての文字のサブセットです。簡単に表現すると、全ての一般的な言語の全ての共通文字が含まれています。

BMPに含まれない最も重要な文字は、[追加多言語面](https://ja.wikipedia.org/wiki/%E8%BF%BD%E5%8A%A0%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2)または[追加漢字面](https://ja.wikipedia.org/wiki/%E8%BF%BD%E5%8A%A0%E6%BC%A2%E5%AD%97%E9%9D%A2)に属する文字です。例えば、以下のようなものです。

* 歴史的な文字や記号、特定の分野で使用される表記法など。エジプト象形文字、現代音楽の楽譜、数学の英数字など。
* Emojiやその他の絵文字。
* トランプ、マージャン、ドミノなどのゲーム記号。
* 日中韓の漢字で、以前の文字符号化規格に含まれなかったもの。
:::

### 2. 構造型
* Cypherクエリから返すことができます。
* [パラメータ](https://neo4j.com/docs/cypher-manual/current/syntax/parameters/)として使用不可です。
* プロパティとして保存不可です。
* [Cypherリテラル](https://neo4j.com/docs/cypher-manual/current/syntax/expressions/)を使って構築不可です。

構造の種類は以下の通りです。
* __ノード__
    * ID
    * ラベル（複数可）
    * マップ (プロパティの)
:::note info
ラベルは値ではなく、パターンシンタックスの一種です。
:::

* __リレーションシップ__
    *  ID
    * タイプ
    * マップ (プロパティの)
    * 開始ノードのID
    * 終了ノードのID
 
* __パス__（ノードとリレーションシップの交互配列）

:::note info
ノード、リレーションシップ、パスは、パターンマッチングの結果として返されます。Neo4jでは、全てのリレーションシップは方向性を持っています。しかし、クエリ時に無向性のリレーションシップの概念を持つことができます。
:::

### 3. 複合型
* Cypherクエリから返すことができます。
*  [パラメータ](https://neo4j.com/docs/cypher-manual/current/syntax/parameters/)として使用可能です。
*  プロパティとして保存不可です。
* [Cypherリテラル](https://neo4j.com/docs/cypher-manual/current/syntax/expressions/)を使って構築可能です。

複合型の種類は以下の通りです。

* __リスト__
雑多な値の順序付きコレクションです。各値は任意のプロパティ型、構造型または複合型を持ちます。
* __マップ__
 キーとバリュー( _Key_ , _Value_ )のペアの雑多な値、非順序のコレクションです。
    *  _Key_ はString型です。
    * _Value_ は、任意のプロパティ、構造型、または複合型を持ちます。
::: note
複合型は、`null`を含むこともできます。
:::
`null`を使用する場合は、特別な注意が必要です（[`null`の使用](https://neo4j.com/docs/cypher-manual/current/syntax/working-with-null/)を参照）。

## 名前付けのルールと推奨事項
:::note
本節では、ノード・ラベル、リレーションシップ・タイプ、プロパティ名、変数、インデックス、および制約の命名に関するルールと推奨事項について説明します。
:::

### 1. 命名規則
* 英字
    * 名前はアルファベットで始めてください。
    * `å`, `ä`, `ö`, `ü` などの「非英語」文字が含まれます。
* 数字
    * 名前は数字で始めてはいけません。
    * 例として、`1first`はダメですが、`first1`はOKです。
* 記号
    * 名前に記号を含めることはできません。ただし、`my_variable`のようにアンダースコアを使用する場合と、`$myParam`のように`$`を最初の文字として使用して[パラメータ](https://neo4j.com/docs/cypher-manual/current/syntax/parameters/)を表す場合は例外です。

* 長さ
    * Neo4jのバージョンにより、`65535` `(2^16 - 1)`字または`65534`字までと非常に長くすることができます。
* 大文字と小文字の区別
    * 名前は大文字と小文字を区別します。したがって、`:PERSON`, `:Person`, `:person`は3つの異なるラベルであり、`n`と`N`は2つの異なる変数となります。
* スペース
    * 先頭と末尾のスペースは自動的に削除されます。例えば、`MATCH ( a ) RETURN a`は、`MATCH (a) RETURN a`と同じ意味です。
  
:::note
数字、記号、空白文字を含む非英字を名前に使用することができますが、バッククオート（\`）を使用してエスケープする必要があります。例えば、`` `^n` ``, `` `1first` ``, `` `$$n` ``, `` `my variable has spaces` ``などです。データベース名は例外で、エスケープの必要なくドット（.）を含むことができます。例えば、`` foo.bar.baz ``というデータベース名は完全に有効です。
:::

### 2. スコープとネームスペースのルール
* ノードのラベル、リレーションシップのタイプ、プロパティ名は、名前を再利用することができます。
    * 以下のクエリ（ラベル、タイプ、プロパティ名に`a`を使用）は有効です。
    `CREATE (a:a {a: 'a'})-[r:a]->(b:a {a: 'a'})`
* ノードとリレーションシップの変数は、同じクエリスコープ内で名前を再利用してはいけません。
    * 以下のクエリは、ノードとリレーションシップの両方が a という名前を持っているため無効です。
    `CREATE (a)-[a]->(b)`

### 3. 推奨される命名規則
以下は推奨される命名規則です。
| 項目 | 命名規則 | 例 |
|---|---|---|
| ノードのラベル  | パスカルケース  | ×：`vehicle_owner`<br>〇：`:VehicleOwner`  |
| リレーションシップのタイプ  | スネークケース<br>全て大文字  | ×：`ownsVehicle`<br>〇：`:OWNS_VEHICLE`  |

# 式
:::note
本節では、Cypherの式の概要と例を説明します。
:::

## 1. 一般的な式
:::note
Cypherのほとんどの式は、その内部式のいずれかが`null`の場合、`null`と評価されます。特筆すべき例外は、演算子`IS NULL`と`IS NOT NULL`です。
:::

Cypherの式には次のようなものがあります。
| 式 | 例 |
|---|---|
| 10進（整数または浮動小数点）リテラル  |`13`, `-40000`, `3.14`   |
| 科学的記数法の10進数（整数または浮動小数点）リテラル |`6.022E23`   |
| `0x`で始まる16進数の整数リテラル  |`0x13af`, `0xFC3A9`, `-0x66eff`   |
| `0o`または`0`から始まる8進数の整数リテラル  |`0o1372`、`02127`、`-0o5671`   |
| 文字列リテラル  |`'Hello'`, `"World"`   |
| ブール型のリテラル  |`true`, `false`   |
| 変数  | `n`, `x`, `rel`, `myFancyVariable`,  `` `A name with weird stuff in it[]!` ``  |
| プロパティ  | `n.prop`, `x.prop`, `rel.thisProperty`, ``myFancyVariable.`(weird property name)` ``   |
| ダイナミックプロパティ  | `n["prop"]`, `rel[n.city + n.zip]`, `map[coll[0]]`   |
| パラメータ  |`$param`, `$0`   |
| 式のリスト  | `[a', 'b']`, `[1, 2, 3]`, `['a', 2, n.property, $param]`, `[]`   |
| 関数呼び出し  | `length(p)`, `nodes(p)`   |
| 集計関数  |`avg(x.prop)`, `count(*)`   |
| パスのパターン  |`(a)-[r]->(b)`, `(a)-[r]-(b)`, `(a)--(b){+`, `(a)-->()<--(b)`   |
| 演算子の応用  |`1 + 2`, `3 < 4`   |
| 述語式（真か偽を返す式）  | `a.prop = 'Hello'`, `length(p) > 10`, `a.name IS NOT NULL`   |
|存在サブクエリ（真または偽を返す式）   | `EXISTS { MATCH (n)-[r]→(p) WHERE p.name = 'Sven' }`   |
| 正規表現  | `a.name =~ 'Tim.*'`   |
| 大文字と小文字を区別する文字列マッチング式  |`a.surname STARTS WITH 'Sven'`, `a.surname ENDS WITH 'son'`, `a.surname CONTAINS 'son'`   |
| `CASE`式  |   |
   
## 2. 文字列リテラルに関する注意
文字列リテラルは、以下のエスケープシーケンスを利用できます。
| エスケープシーケンス | 文字 |
|---|---|
| `\t` | タブ  |
| `\b` | バックスペース  |
| `\n` | 改行  |
| `\r` | キャリッジリターン  |
| `\f` | フォームフィード  |
| `\'` | シングルクォーテーション  |
| `\"`  | ダブルクォーテーション  |
| `\\`  | バックスラッシュ  |
| `\?`  | Unicode UTF-16 コードポイント (`\u`に続いて4桁の16進数が必要)  |
| `\Uxxxxxx`  | Unicode UTF-32 コードポイント (`\U`に続いて8桁の16進数が必要)  |

### 3. CASE式
一般的な条件式は`CASE`構文で表現できます。`CASE`には、複数の値に対して式を比較できる単純な形式と、複数の条件文を表現できる汎用的な形式の2種類があります。

:::note
CASEはRETURNやWITHの一部としてのみ使用でき、その結果を後続の句や文で使用することができます。
:::
以下のグラフを例にします。
![](https://kroki.io/graphviz/svg/eNq1ks9PgzAUx-_7K17mgYsm48eMxsyEDQ5GxWQePFAOBZ5ArO1SWBay7X-3ZQvgWDzNE-17zaffTx9pkUm6yuEFtsBFihCWOV3hTGIiZAplVTO1EWueYho9jACCCYTqA8BojAxmMN66O06_US2J4bIiQWIQRjNdsO8IwxrLphdLseG6tx8rQHRg3TxCYB2JiWBCauKVhbZj346b6qfg1flOm-A5ePt4J_wEa14aaw7M5535XMSdtzXte7M1_tY2m3z25fNprDPAOnhPJ2ex_U6LfXWXyyff64GtgfiiE1_kVLKiN_Sp3ZPPJOLJ0K3_sbcHIb0upEd5gUzn-Ot3dAYIfzcYI5WS1roSEkNwVbpWzWojjotcCatjEWHt5X75VbDufRyzvXO0_wHCju7A)


### 3.1. 単純なCASE式：複数の値に対する式の比較
式は計算され、一致するものが見つかるまで`WHEN`句と順番に比較されます。一致するものがない場合、`ELSE`句の式が返される。ただし、`ELSE`句がなく、一致するものが見つからない場合は、`null`が返されます。
注：要は`test`の値が`value`ならば`result`を戻します。同様に他の`WHEN`以降と比較していき、一致するものが全く無ければ `default`を戻します。
__構文__

```Cypher:Cypher
CASE test
  WHEN value THEN result
  [WHEN ...]
  [ELSE default]
END
```

__引数__

| 名前 | 説明 |
|---|---|
| `test`  | 有効な式  |
| `value`  | 結果が`test`と比較される式  |
| `result`  | `test`が`value`と一致した場合に出力として返される式  |
| `default`  | 何もマッチしない場合、`default`が返されます  |



__クエリ__
```Cypher:Cypher
MATCH (n)
RETURN
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS result
``` 

__表1. 結果__
| result |
|---|
| `2`<br> `1`<br> `3` <br> `2`  <br> `1`  |
| Rows: 5|

### 3.2. 一般的なCASE形式：複数の条件式を表現可能
述語は、`true`値が見つかるまで順に評価され、その結果値が使われます。一致するものがない場合は、`ELSE`句内の式が戻されます。しかし、`ELSE`句がなく、マッチするものが見つからなければ、`null`が戻されます。

__構文__
```Cypher:Cypher
CASE
  WHEN predicate THEN result
  [WHEN ...]
  [ELSE default]
END
```

__引数__
| 名前 | 説明 |
|---|---|
| `predicate`  | 有効な選択肢を見つけるためにテストされる述語  |
| `result`  | `predicate`が`true`と評価された場合に出力として返される式  |
| `default`  | 何もマッチしない場合、`default`が返されます  |

__クエリ__
```Cypher:Cypher
MATCH (n)
RETURN
CASE
  WHEN n.eyes = 'blue' THEN 1
  WHEN n.age < 40      THEN 2
  ELSE 3
END AS result
```

__表2. 結果__
| result |
|---|
| `2`<br> `1`<br> `3`<br> `3`<br>`1`  |
| Rows: 5|

### 3.3. 単純なCASEと一般的なCASEの使い分け
2つの式の構文は非常に似ているため、どちらの式を使用すべきかわからない場合があります。このシナリオを次のクエリで説明します。このクエリでは`n.age`が`null`の場合、`age_10_years_ago`は`-1`であることが期待されています。

__クエリ__
```Cypher:Cypher
MATCH (n)
RETURN n.name,
CASE n.age
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago
```
しかし、この問い合わせは単純な`CASE`式を使って書かれているため、`Daniel`というノードの`age_10_years_ago`は`-1`ではなく、`null`になっています。これは`n.age`と`n.age IS NULL`とで比較が行われたためです。`n.age IS NULL`はブール値で`n.age`は整数値なので、分岐`WHEN n.age IS NULL THEN -1`は決して行われません。その結果、代わりに`ELSE n.age - 10`分岐が実行され、`null`が返されます。

__表3. 結果__
| n.name	 |age_10_years_ago |
|---|---|
| `"Alice"`<br>`"Bob"`<br>`"Charlie"`<br>`"Daniel"`<br> `"Eskil"`   | `28`<br>`15`<br>`43`<br>`<null>`<br>`31`   |
| Rows: 5||

期待通りの動作をする修正されたクエリは、以下の一般的な`CASE`式で与えられます。
__クエリ__
```Cypher:Cypher
MATCH (n)
RETURN n.name,
CASE
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago
```

`age_10_years_ago`は`Daniel`という名前のノードに対して正しく`-1`を返していることがわかります。

__表4. 結果__
| n.name	 |age_10_years_ago |
|---|---|
| `"Alice"`<br>`"Bob"`<br>`"Charlie"`<br>`"Daniel"` <br>`"Eskil"`   | `28`<br> `15` <br>`43`<br>`-1`<br>`31`  |
| Rows: 5|

### 3.4. CASEの結果を後続の節または文に使用する
`CASE`の結果を使用して、ノードまたはリレーションシップにプロパティを設定することができます。例えば、ノードを直接指定する代わりに、式で選択されたノードのプロパティを設定することができます。
__クエリ__
```Cypher:
MATCH (n)
WITH n,
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS colourCode
SET n.colourCode = colourCode
```

`SET`句の使い方の詳細については、[SET](https://neo4j.com/docs/cypher-manual/current/clauses/set/)を参照してください。
__表5. 結果__
| `(empty result)` |
|---|
| Rows: 0<br> Properties set: 5|

# 変数
:::note
本節では、Cypherにおける変数の概要を説明します。
:::

パターンやクエリの一部を参照するとき、名前を付けて参照します。その名前を変数と呼びます。
この例では、

```Cypher:Cypher
MATCH (n)-->(b)
RETURN b
```

変数は`n`と`b`です。
変数の命名に関する情報は、[こちら](#名前付けのルールと推奨事項)を参照して下さい。

:::note warn
__変数は、同じクエリの中でしか見ることができません。__
変数は後続のクエリに持ち越されません。複数の問い合わせ部分が`WITH`によって連結されている場合、変数は次の部分に引き継がれるように`WITH`句にリストアップされなければなりません。詳しくは[WITH](https://neo4j.com/docs/cypher-manual/current/clauses/with/)を参照してください。
:::

# 予約語
:::note
本節では、Cypherの予約語の一覧を示します。
:::
予約語とは、Cypherの中で特別な意味を持つ言葉です。予約語のリストは、それらが引き出されるカテゴリでてグループ化されています。さらに、将来の使用のために予約されているものもいくつかあります。

予約語は、以下の文脈では識別子として使用することはできません。
* 変数
* 関数名
* パラメータ

予約語がエスケープされた場合、つまり `AND` のようにバッククォーテーション`` ` ``で囲われた場合は、上記のコンテキストで有効な識別子になります。


## 1. 句
`CALL`、`CREATE`、`DELETE`、`DETACH`、`EXISTS`、`FOREACH`、`LOAD`、`MATCH`、`MERGE`、`OPTIONAL`、`REMOVE`、`RETURN`、`SET`、`START`、`UNION`、`UNWIND`、`WITH`
 
## 2. サブ句
`LIMIT`、`ORDER`、`SKIP`、`WHERE`、`YIELD`

## 3. 修飾子
`ASC`、`ASCENDING`、`ASSERT`、`BY`、`CSV`、`DESC`、`DESCENDING`、`ON`

## 4. 式
`ALL`、`CASE`、`ELSE`、`END`、`THEN`、`WHEN`

## 5. 演算子
`AND`、`AS`、`CONTAINS`、`DISTINCT`、`ENDS`、`IN`、`IS`、`NOT`、`OR`、`STARTS`、`XOR`

## 6. スキーマ
`CONSTRAINT`、`CREATE`、`DROP`、`EXISTS`、`INDEX`、`NODE`、`KEY`、`UNIQUE`

## 7. ヒント
`INDEX`、`JOIN`、`PERIODIC`、`COMMIT`、`SCAN`、`USING`

## 8. リテラル
、`false`、`null`、`true`

## 9. 将来の使用のために予約されているもの
`ADD`、`DO`、`FOR`、`MANDATORY`、`OF`、`REQUIRE`、`SCAlAR`
# パラメータ
:::note
本節では、パラメータ化クエリを説明します。
:::
## 1. はじめに
Cypherはパラメータを使った問い合わせをサポートしています。パラメータ化クエリとは、パラメータにプレースホルダを使用し、実行時にパラメータ値を与えるクエリのことです。これは、開発者がクエリを作成するために文字列を構築する必要がないことを意味します。さらに、Cypherでは、パラメータによって実行プランのキャッシュが容易になり、クエリの実行時間が短縮されます。

パラメータを使用できるのは以下です。
* リテラルと式
* ノードとリレーションシップのID

パラメータは、以下の構成要素には使用できません。これらは、クエリプランにコンパイルされるクエリ構造の一部を形成するためです。
* プロパティキー。したがって、`MATCH (n) WHERE n.$param = 'something'` は無効です。
* リレーションシップタイプ
* ラベル

パラメータは、文字と数字、およびこれらの任意の組み合わせで構成することができますが、数字や通貨記号で始めることはできません。

クエリ実行時のパラメータの設定はクライアント環境に依存します。例えば、
* Cypher Shellでパラメータを設定するには、`:param name => 'Joe'`とします。詳細は、[操作マニュアル → Cypher Shell - クエリパラメータ ](https://neo4j.com/docs/operations-manual/4.4/tools/cypher-shell/#cypher-shell-parameters)を参照してください。
* Neo4jブラウザの場合は、Cypher Shellと同じ構文で、`:param name => 'Joe'`とします。
* ドライバを使用する場合、構文は言語に依ります。[Neo4jドライバのマニュアル](https://neo4j.com/docs)の _Transactions_ にある例を参照してください。
* Neo4j HTTP API を使用する場合は、[HTTP APIのドキュメント](https://neo4j.com/docs/http-api/4.4/#http-api)を参照してください。

以下に、パラメータの使用例の一覧を示します。これらの例では、パラメータはJSONで与えられます。パラメータをどのように送信するかは、使用するドライバに依存します。

:::note
古いパラメータ構文である`{param}`はNeo4j 3.0で非推奨となり、Neo4j 4.0で完全に削除されました。これを使用すると、シンタックスエラーが発生します。しかし、クエリの前に`CYPHER 3.5`を付けると、警告は出ますが、まだ使用することは可能です。詳しくは[Cypher互換性](https://neo4j.com/docs/cypher-manual/current/deprecations-additions-removals-compatibility/#cypher-compatibility)を参照してください。
:::

## 2. 自動パラメータ化
クエリがパラメータを使用しない場合、Cypherはとにかくパラメータを推論しようとします。クエリ内の各リテラルは、パラメータに置き換えられます。これにより、リテラル以外は同一の問い合わせに対して、計算された計画の再利用性を高めることができます。この動作に依存することはお勧めしません。ユーザは適切と思われるところでパラメータを使用すべきです。

:::note
少なくとも1つのパラメータがクエリで使用されている場合、そのクエリでは自動パラメータ化は行われません。これは、残りのリテラルがパラメータに変換されないことを意味します。
:::

## 3. 文字列リテラル
__パラメータ__
```Javascript:JavaScript
{
  "name" : "Johan"
}
```
__クエリ__
```Cypher:Cypher
MATCH (n:Person)
WHERE n.name = $name
RETURN n
```

この構文では、パラメータも使用できます。
__パラメータ__
```Javascript:JavaScript
{
  "name" : "Johan"
}
```

__クエリ__
```Cypher:Cypher
MATCH (n:Person {name: $name})
RETURN n
```

## 4. 正規表現
__パラメータ__
```Javascript:JavaScript
{
  "regex" : ".*h.*"
}
```
__クエリ__
```Cypher:Cypher
MATCH (n:Person)
WHERE n.name =~ $regex
RETURN n.name
```
## 5. 大文字小文字を区別した文字列パターンマッチング
__パラメータ__
```Javascript:JavaScript
{
  "name" : "Michael"
}
```
__クエリ__
```Cypher:Cypher
MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name
```

## 6. プロパティを持つノードの作成
__パラメータ__
```Javascript:JavaScript
{
  "props" : {
    "name" : "Andy",
    "position" : "Developer"
  }
}
```
__クエリ__
```Cypher:Cypher
CREATE ($props)
```
## 7. プロパティを持つ複数のノードの作成
__パラメータ__
```Javascript:JavaScript
{
  "props" : [ {
    "awesome" : true,
    "name" : "Andy",
    "position" : "Developer"
  }, {
    "children" : 3,
    "name" : "Michael",
    "position" : "Developer"
  } ]
}
```
__クエリ__
```Cypher:Cypher
UNWIND $props AS properties
CREATE (n:Person)
SET n = properties
RETURN n
```
## 8. ノード上の全てのプロパティを設定する
これは、現在のプロパティを全て置き換えることに注意してください。
__パラメータ__
```Javascript:JavaScript
{
  "props" : {
    "name" : "Andy",
    "position" : "Developer"
  }
}
```
__クエリ__
```Cypher:Cypher
MATCH (n:Person)
WHERE n.name = 'Michaela'
SET n = $props
```
## 9. SKIPとLIMIT
__パラメータ__
```Javascript:JavaScript
{
  "s" : 1,
  "l" : 1
}
```
__クエリ__
```Cypher:Cypher
MATCH (n:Person)
RETURN n.name
SKIP $s
LIMIT $l
```
## 10. ノードID
__パラメータ__
```Javascript:JavaScript
{
  "id" : 0
}
```
__クエリ__
```Cypher:Cypher
MATCH (n)
WHERE id(n) = $id
RETURN n.name
```
## 11. 複数のノードID
__パラメータ__
```Javascript:JavaScript
{
  "ids" : [ 0, 1, 2 ]
}
```
__クエリ__
```Cypher:Cypher
MATCH (n)
WHERE id(n) IN $ids
RETURN n.name
```

## 12. プロシージャの呼び出し
__パラメータ__
```Javascript:JavaScript
{
  "indexname" : "My index"
}
```
__クエリ__
```Cypher:Cypher
CALL db.resampleIndex($indexname)
```

# 演算子
:::note
本節では、演算子の概要を説明します。
:::
## 1.演算子の一覧

| 演算子名 | 演算子 
|---|---|
|[集計演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-aggregation)   | `DISTINCT`  |
|[プロパティ演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-property)   | 静的プロパティアクセスの場合は`.`<br>動的プロパティアクセスの場合は`[]`<br>全てのプロパティを置換する場合は`=`<br>特定のプロパティを変更する場合は`+=`  |
|[数学演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-mathematical)   |`+`, `-`, `*`, `/`, `%`, `^`|
|[比較演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-comparison)   |`=`, `<>`, `<`, `>`, `<=`, `>=`, `IS NULL`, `IS NOT NULL`|
|[文字列固有の比較演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-comparison)   |`STARTS WITH`, `ENDS WITH`, `CONTAINS`, `=~`(正規表現用)   |
|[ブール演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-boolean)   |`AND`, `OR`, `XOR`, `NOT`   |
|[文字列演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-string)   |`+`(連結)   |
|[時間演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-temporal)   |継続時間と一時インスタンス/継続時間の間の演算には`+`と`-`<br>継続時間と数値の間の演算には`*`と`/`   |
|[マップ演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-map)   |キーによる静的な値アクセスの場合は`.`、キーによる動的な値アクセスの場合は`[]`   |
|[リスト演算子](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#query-operators-list)   |`+`(連結)<br>`IN`(リスト内のエレメントの存在をチェック)<br>`[]`(エレメントに動的にアクセス)   |

## 2. 集計演算子
集計演算子は次のもので構成されます。
* 重複値の削除:`DISTINCT`

## 2.1.DISTINCT演算子の使用
`Person`ノードから一意の目の色を取得します。
__クエリ__
```Cypher:Cypher
CREATE
  (a:Person {name: 'Anne', eyeColor: 'blue'}),
  (b:Person {name: 'Bill', eyeColor: 'brown'}),
  (c:Person {name: 'Carol', eyeColor: 'blue'})
WITH [a, b, c] AS ps
UNWIND ps AS p
RETURN DISTINCT p.eyeColor
```
__'Anne'__ と __'Carol'__ は二人とも青い目ですが、 __'blue'__ は一度だけ返されます。

表1. 結果
|P.eyeColor   |
|---|
|`"blue"` <br>`"brown"`   |
|Rows: 2<br>Nodes created: 3<br>Properties set: 6<br>Labels added: 3   |

`DISTINCT`は通常、[集計関数](https://neo4j.com/docs/cypher-manual/current/functions/aggregating/)と組み合わせて使用されます。
## 3.プロパティ演算子
プロパティ演算子はノードまたはリレーションシップに関連し、次のもので構成されます。
* ドット演算子`.`
ノードまたはリレーションシップのプロパティに静的にアクセスします。
* サブスクリプト演算子`[]`
ノードまたはリレーションシップのプロパティに動的にアクセスします。
* プロパティ置換演算子`=`
ノードまたはリレーションシップのすべてのプロパティを置き換えます。
* プロパティ変換演算子`+=`
ノードまたは関係の特定のプロパティを設定します。

### 3.1. .演算子を使用してノードまたはリレーションシップのプロパティに静的にアクセスする
__クエリ__
```Cypher:Cypher
CREATE
  (a:Person {name: 'Jane', livesIn: 'London'}),
  (b:Person {name: 'Tom', livesIn: 'Copenhagen'})
WITH a, b
MATCH (p:Person)
RETURN  p.name
```


__表2. 結果__
| p.name |
|---|
|`"Jane"`<br>`"Tom"`   |
|Rows: 2<br>Nodes created: 2<br>Properties set: 4<br>Labels added: 2   |

### 3.2. []演算子を使用した動的に計算されたプロパティキーのフィルタリング
__クエリ__
```Cypher:Cypher
CREATE
  (a:Restaurant {name: 'Hungry Jo', rating_hygiene: 10, rating_food: 7}),
  (b:Restaurant {name: 'Buttercup Tea Rooms', rating_hygiene: 5, rating_food: 6}),
  (c1:Category {name: 'hygiene'}),
  (c2:Category {name: 'food'})
WITH a, b, c1, c2
MATCH (restaurant:Restaurant), (category:Category)
WHERE restaurant["rating_" + category.name] > 6
RETURN DISTINCT restaurant.name
```
__表3. 結果__
| restaurant.name |
|---|
|`"Hungry Jo"`   |
|Rows: 1<br>Nodes created: 4<br>Properties set: 8<br>Labels added: 4   |

動的プロパティアクセスの詳細については、[基本的な使い方](https://neo4j.com/docs/cypher-manual/current/clauses/where/#query-where-basic)を参照してください。

:::note
`null`に関する`[]`演算子の動作については、[ここ]()で詳しく説明します。
:::

### 3.3. =演算子を使用したノードまたはリレーションシップのすべてのプロパティの置換
__クエリ__
```Cypher:Cypher
CREATE (a:Person {name: 'Jane', age: 20})
WITH a
MATCH (p:Person {name: 'Jane'})
SET p = {name: 'Ellen', livesIn: 'London'}
RETURN p.name, p.age, p.livesIn
```
ノード上の既存のプロパティはすべて、マップ内のプロパティに置き換えられます。たとえば、`name`プロパティは`Jane`から`Ellen`に更新され、`age`プロパティは削除され、`livesIn`プロパティが追加されます。

__表4. 結果__
| p.name | p.age | p.livesIn |
|---|---|---|
|`"Ellen"`   |`<null>`   |`"London"`   |
|Rows: 1<br>Nodes created: 1<br>Properties set: 5<br>Labels added: 1   ||   |

プロパティ置換演算子`=`の使用方法の詳細は、[マップと`=`を使用してすべてのプロパティを置換する]()を参照してください。

### 3.4. +=演算子を使用してノードまたはリレーションシップの特定のプロパティを変更する
__クエリ__
```Cypher:Cypher
CREATE (a:Person {name: 'Jane', age: 20})
WITH a
MATCH (p:Person {name: 'Jane'})
SET p += {name: 'Ellen', livesIn: 'London'}
RETURN p.name, p.age, p.livesIn
```

ノード上のプロパティは、マップで提供されているプロパティによって次のように更新されます。`name`プロパティは`Jane`から`Ellen`に更新され、`age`プロパティは変更されずに残り、`livesIn`プロパティが追加されます。


__表5. 結果__
| p.name | p.age | p.livesIn |
|---|---|---|
|`"Ellen"`   |`20`   |`"London"`   |
|Rows: 1<br>Nodes created: 1<br>Properties set: 4<br>Labels added: 1   ||   |

プロパティ変換演算子`+=`の使用方法の詳細については、[「マップと+=を使用して特定のプロパティを変換する」]()を参照してください。

## 4. 数学演算子
算術演算子は次のもので構成されます。
* 加算:`+`
* 減算または単項マイナス:`-`
* 乗算:`*`
* 除算:`/`
* 剰余:`%`
* 累乗:`^`

## 4.1. 指数演算子^を使用する
__クエリ__
```Cypher:Cypher
WITH 2 AS number, 3 AS exponent
RETURN number ^ exponent AS result
```
__表6. 結果__
| result |
|---|
|`8.0`   |
|Rows: 1   |

### 4.2. 単項マイナス演算子の使用-
__クエリ__
```Cypher:Cypher
WITH -3 AS a, 4 AS b
RETURN b - a AS result
```

__表7. 結果__
| result |
|---|
|`7`   |
|Rows: 1   |

## 5. 比較演算子
比較演算子には次のものがあります。
* 等値:`=`
* 不等:`<>`
* 小なり:`<`
* 大なり:`>`
* 以下:`<=`
* 以上:`>=`
* `IS NULL`
* `IS NOT NULL`

### 5.1. 文字列固有の比較演算子は、次のもので構成されます。
* `START WITH`:大文字と小文字を区別して文字列のプレフィックス検索を実行します。
* `ENDS WITH`:大文字と小文字を区別した文字列のサフィックス検索を実行します
* `CONTAINS`:大文字と小文字を区別して文字列内の包含検索を実行します
* `=~`:正規表現と一致
### 5.2. 2つの数値の比較
__クエリ__
```Cypher:Cypher
WITH 4 AS one, 3 AS two
RETURN one > two AS result
```

__表8. 結果__
| result |
|---|
|`true`   |
|Rows: 1   |

比較演算子の動作の詳細は、[「値の等価と比較」]()を参照してください。また、これらの使用例は、[「範囲の使用」]()を参照してください。

### 5.3. STARTS WITHを使用した名前のフィルタリング
__クエリ__
```Cypher:Cypher
WITH ['John', 'Mark', 'Jonathan', 'Bill'] AS somenames
UNWIND somenames AS names
WITH names AS candidate
WHERE candidate STARTS WITH 'Jo'
RETURN candidate
```
__表9. 結果__
| candidate |
|---|
|`"John"`<br>`"Jonathan"`   |
|Rows: 2   |

[文字列マッチング]()には、文字列固有の比較演算子に関する詳細情報と、その使用方法を示す追加の例が含まれています。

### 5.4. 値の等値と比較
#### 5.4.1. 等値
Cypherは、`=`演算子と`<>`演算子を使用した等値による値の比較([値と型]()を参照)をサポートしています。

同じタイプの値は、同じ値である場合にのみ等しくなります(例:`3=3`および`"x"<>"xy"`)。

マップは、全く同じキーを同じ値にマップする場合にのみ等しくなります。リストは、同じ一連の同じ値(`[3,4]=[1+2,8/2]`など)を含む場合にのみ等しくなります。

異なるタイプの値は、次の規則に従って等しいと見なされます。
* パスはノードとリレーションシップが交互に現れるリストとして扱われ、ノードとリレーションシップの全く同じシーケンスを含む全てのリストと等しくなります。
* `=`演算子と`<>`演算子の両方を使用して、任意の値を`null`に対してテストすると、常に`null`と評価されます。これには、`null = null`と`null <> null`が含まれます。値`v`が`null`かどうかを確実にテストする唯一の方法は、特殊な`v IS NULL`または`v IS NOT NULL`等価演算子を使用することです。`v IS NOT NULL`は`NOT(v IS NULL)`と等価です。

値のタイプの他のすべての組み合わせは、相互に比較できません。特に、ノード、リレーションシップ、およびリテラルマップは相互に比較不能です。
比較できない値を比較することはエラーです。

## 5.5.値の順序付けと比較
比較演算子`<=`,`<`(昇順)および`>=`,`>`(降順)は、順序付けのために値を比較するために使用されます。次に、比較の実行方法の詳細を示します。
* 数値は、数値順序を使用して順序付けのために比較されます(たとえば、`3 < 4`はtrue)。
* `java.lang.Double.NaN`を伴う全ての比較可能性テスト(<、⇐、>、>=)はfalseと評価されます。たとえば、bがNaNの場合、`1 > b`と`1 < b`は両方ともfalseになります。
* 文字列値は、辞書式順序(`"x" < "xy"`など)を使用して順序が比較されます。
* ブール値は、`false < true`の順序で比較されます。
* 空間値の比較:
    * ポイント値は、同じ座標参照システム(Coordinate Reference System; CRS)内でのみ比較できます。それ以外の場合、結果はnullになります。
    * 同じCRS内の2つの点`a`および`b`について、`a.x > b.x`かつ`a.y > b.y`(3D点の場合はさらに`a.z > b.z`)の場合、`a`は`b`より大きいと見なされます。
    * `a.x < b.x`かつ`a.y < b.y`(3D点の場合はさらに`a.z < b.z`)の場合、`a`は`b`より小さいと見なされます。
    * 上記が成立しない場合、ポイントは比較不能と見なされ、ポイント間の比較演算子は`null`を返します。

* 空間値の順序:
    * `ORDER BY`では、すべての値が順序付け可能である必要があります。
    * ポイントは配列の後、一時的なタイプの前に並べられます。
    * 異なるCRSのポイントは、CRSコード(SRIDフィールドの値)によって順序付けられます。現在サポートされている[座標参照システム]()のセットでは、次の順序を意味します:4326,4979,7302,9157
    * 同じCRSの点は、各座標値によって順番に並べられます。最初に`x`、次に`y`、最後に`z`です。
    * この順序は空間インデックスによって返される順序とは異なることに注意してください。空間インデックスは空間充填曲線の順序になります。
* 時間値の比較
    * [時間のインスタント値]()は同じタイプ内で比較可能です。あるインスタント（時点）が他のインスタントよりも前に発生した場合は、そのインスタントより小さいとみなされ、後に発生した場合はそのインスタントより大きいとみなされます。
    * 同じ時点で発生する(ただしタイムゾーンが異なる)インスタント値は同じとは見なされないため、予測可能な方法で順序付けする必要があります。Cypherは、時点を時間順に並べた後に、有効なタイムゾーンオフセットによって西(UTCからの負のオフセット)から東(UTCからの正のオフセット)にインスタント値を順序付けることを規定しています。これは、同じ時点は最も早い現地時間の時間で順序付けられるという効果があります。もし、2つのインスタント値が同じ時点を表し、タイムゾーンオフセットは同じであるが、タイムゾーンの名前が異なる（ _Time_ のみオフセットを持つので、 _DateTime_ のみ可能です）場合、これらの値は同等とは見なされず、3番目の順序付け要素として、タイムゾーン識別子によってアルファベット順に順序付けられます。もし、タイプ、時点、オフセット、およびタイムゾーン名がすべて等しい場合、これらの値は全て等しく、順序の違いは観察できません。
    * [期間( _Duration_ )]()値は比較できません。年月日（_year_, _month_, _day_）が具体的にわからないと、その長さは不明なためです。期間値は比較できないため、2つの期間値に比較演算子を適用した結果は`null`になります。

* 時間値の順序付け
    * `ORDER BY`は、全ての値が順序付け可能である必要があります。
    * 時間インスタンスは、空間インスタンスの後、文字列の前に順序付けられます。
    * 比較可能な値は、その比較順序によって示されるのと同じ順序付けられるべきです。
    * 時間のインスタント値は、最初に型によって順序付けられ、次に型の中において比較順序によって順序付けられます。
    * _Duration_ 値に対して完全な比較順序を定義することはできないので、 _Duration_ に対しては具体的に`ORDER BY`の順序を定義します。
        * _Duration_ 値は、全ての要素を次のように正規化して順序付けられます：全ての年は`365.2425`日(`PT8765H49M12S`)、全ての月は`30.436875`(`1/12`年)日(`PT730H29M06S`)、全ての日は24時間[^1]。

[^1]:https://neo4j.com/docs/cypher-manual/current/syntax/operators/#_footnotedef_1

* 1つの引数が`null`の場合(たとえば、`null < 3`が`null`の場合)、順序を比較します。
* __異なる__ 型の値の __順序付け__
    * 順序は、昇順で、次のリストに従って定義されます。
        * Map
        * Node
        * Relationship
        * List
        * Path
        * DateTime
        * LocalDateTime
        * Date
        * Time
        * LocalTime
        * Duration
        * String
        * Boolean
        * Number
     * `null`値はどの値よりも大きいと見なされます。
* 複合型の値の __順序__
    * [複合型]()(マップやリストなど)では、コンテナの要素はペアで比較されて順序が決定されるため、2つのコンテナ型の順序が決定されます。例えば、`[1,'foo',3]`は`[1,2,'bar']`の前に順序付けられます。これは、`'foo'`が`2`の前に順序付けられるためです。

### 5.6.比較演算の連鎖

比較は任意に連鎖させることができます。例えば、`x < y <= z`は`x < y AND y <= z`と等価です。

形式的には、`a, b, c, ..., y, z`を式、`op1, op2, ..., oPN`を比較演算子とすると、`a op1 b op2 c ... y oPn z`は`a op1 b and b op2 c and ... y opN z`と等価です。

`a op1 b op2 c`は`a`と`c`の間のいかなる種類の比較も意味しないので、例えば`x < y > z`は(エレガントではないでしょうが)完全に合法であることに注意してください。

次に例を示します。
```Cypher:Cypher
MATCH (n) WHERE 21 < n.age <= 30 RETURN n
```
これは以下と等価です。
```Cypher:Cypher
MATCH (n) WHERE 21 < n.age AND n.age <= 30 RETURN n
```
したがって、ageが21～30の全てのノードと一致します。
この構文は、全ての等号`=`と不等号`<>`の比較、および3つより長い連鎖に拡張されます。

:::note info
`=`と`<>`の連鎖は、Cypherでは特別な方法で扱われます。
つまり、`1=1=true`は`1=1 AND 1=true`と等価であり、`(1=1)=true`や`1=(1=true)`とは等価ではありません。
:::

次に例を示します。
```Cypher:Cypher
a < b = c <= d <> e
```
これは以下と等価です。
```Cypher:Cypher
a < b AND b = c AND c <= d AND d <> e
```
## 6.=~とともに正規表現を使用して単語をフィルタする
__クエリ__
```Cypher:Cypher
WITH ['mouse', 'chair', 'door', 'house'] AS wordlist
UNWIND wordlist AS word
WITH word
WHERE word =~ '.*ous.*'
RETURN word
```
__表10.結果__
| word |
|---|
| `"mouse"` <br> `"house"`  |
| Rows: 2|

フィルタリングにおける正規表現の使用に関する詳細と例は、[正規表現](https://neo4j.com/docs/cypher-manual/current/clauses/where/#query-where-regex)を参照してください。

## 7. ブール演算子
論理演算子とも呼ばれるブール演算子は、次のもので構成されます。
* 論理積:`AND`
* 論理和:`OR`
* 排他的論理和:`XOR`
* 否定:`NOT`
`AND`、`OR`、`XOR`、`NOT`の真理値表を以下に示します。

| `a` | `b` | `a AND b` | `a OR b` | `a XOR b` | `NOT a` |
|:-:|:-:|:-:|:-:|:-:|:-:|
| `false`  | `false`  | `false`  | `false`  | `false`  | `true`  |
| `false`  | `null`   | `false`  | `null`   | `null`   | `true` |
| `false`  | `true`   | `false`  | `true`   | `true`   | `true`  |
| `true`   | `false`  | `false`  | `true`   | `true`   | `false` |
| `true`   | `null`   | `null`   | `true`   | `null`   | `false` |
| `true`   | `true`   | `true`   | `true`   | `false`  | `false` |
| `null`   | `false`  | `false`  | `null`   | `null`   | `null`  |
| `null`   | `null`   | `null`   | `null`   | `null`   | `null`  |
| `null`   | `true`   | `null`   | `true`   | `null`   | `null`  | 

### 7.1. ブール演算子を使用した数値のフィルタ
__クエリ__
```Cypher:Cypher
WITH [2, 4, 7, 9, 12] AS numberlist
UNWIND numberlist AS number
WITH number
WHERE number = 4 OR (number > 6 AND number < 10)
RETURN number
```

__表11結果__
| number |
|---|
| `4`<br>`7`<br>`9`  |
| Rows: 3  |

## 8. 文字列演算子
文字列演算子には次のものがあります。
* 文字列の連結:`+`
### 8.1. 2つの文字列を+で連結する
__クエリ__
```Cypher:Cypher
RETURN 'neo' + '4j' AS result
```
__表12. 結果__
| 結果 |
|---|
| `"neo4j"`  |
| Rows: 1  |

## 9. 時間演算子
時間演算子には次のものがあります。
* [時間のインスタント](https://neo4j.com/docs/cypher-manual/current/syntax/temporal/#cypher-temporal-instants)または別の期間に[期間](https://neo4j.com/docs/cypher-manual/current/syntax/temporal/#cypher-temporal-durations)を追加する:`+`
* 時間のインスタントまたは別の期間から期間を差し引く:`-`
* 期間に数値を掛ける:`*`
* 期間を数値で除算する:`/`
次の表は、演算とオペランドタイプの組み合わせごとに、各時間演算子のアプリケーションから返される値のタイプを示しています。

| 演算子 | 左側のオペランド | 右側のオペランド | 結果のタイプ |
|---|---|---|---|
| `+`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-add-subtract-duration-to-temporal-instant)  | 時間のインスタント  | 期間  | 時間のインスタント  |
| `+`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-add-subtract-duration-to-temporal-instant)  | 期間  | 時間のインスタント  | 時間のインスタント  |
| `-`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-add-subtract-duration-to-temporal-instant)  | 時間のインスタント  | 期間  | 時間のインスタント  |
| `+`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-add-subtract-duration-to-duration)  | 期間  | 期間  | 期間  |
| `-`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-add-subtract-duration-to-duration)  | 期間  | 期間  | 期間  |
| `*`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-multiply-divide-duration-number)  | 期間  | [数字](https://neo4j.com/docs/cypher-manual/current/syntax/values/#property-types)  | 期間  |
| `*`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-multiply-divide-duration-number)  |  [数字](https://neo4j.com/docs/cypher-manual/current/syntax/values/#property-types)  | 期間  | 期間  |
| `/`[■](https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-multiply-divide-duration-number)  | 期間  |  [数字](https://neo4j.com/docs/cypher-manual/current/syntax/values/#property-types)  | 期間  |

### 9.1. 時間のインスタントと期間との加減算
__クエリ__
```Cypher:Cypher
WITH
  localdatetime({year:1984, month:10, day:11, hour:12, minute:31, second:14}) AS aDateTime,
  duration({years: 12, nanoseconds: 2}) AS aDuration
RETURN aDateTime + aDuration, aDateTime - aDuration
```

__表13. 結果__
| aDateTime + aDuration | aDateTime - aDuration |
|---|---|
| `1996-10-11T12:31:14.000000002`  | `1972-10-11T12:31:13.999999998`  |
| Rows: 1  |   |