構文
本章では、問い合わせ言語Cypherの構文を説明します。
値と型
本節では、Cypherのデータ型の概要を説明します。
Cypherは、多くのデータ型を非常によくサポートしています。
これらはいくつかのカテゴリに分類され、以下の小節で詳細に説明しています。
- プロパティ型
- Integer, Float, String, Boolean, Point, Date, Time, LocalTime, DateTime, LocalDateTime, Duration
- 構造型
- Node, Relationship, Path
- 複合型
- List, Map
1. プロパティ型
- Cypherクエリから返すことができます。
- パラメータとして使用可能です。
- プロパティとして保存可能です。
- Cypherリテラルを使って構築可能です。
プロパティの種類は以下の通りです。
-
Number
抽象的な型であり、Integer と Float のサブタイプを持ちます。 - String
- Boolean
-
Point
空間型です。 -
Date, Time, LocalTime, DateTime, LocalDateTime, Duration
時間型です。
形容詞の numeric は、Cypherの関数や式を説明する文脈で使用される場合、任意の型の数(IntegerでもFloatでも)を適用できることを表します。
単純な型の同種のリストもプロパティとして保存できますが、一般的なリスト(複合型を参照)は保存できません。
Cypherはまた、バイト配列のパススルーサポートを提供しており、プロパティ値として保存することができます。バイト配列は Cypherでは優れたデータ型とは見なされていないため、リテラル表現を持ちません。
特殊文字のソートについて
Basic Multilingual Plane (BMP) に属さない文字を含む文字列は、Neo4jでは一貫性のない、あるいは非決定的な順序になることがあります。BMPは、Unicodeで定義された全ての文字のサブセットです。簡単に表現すると、全ての一般的な言語の全ての共通文字が含まれています。
BMPに含まれない最も重要な文字は、追加多言語面または追加漢字面に属する文字です。例えば、以下のようなものです。
- 歴史的な文字や記号、特定の分野で使用される表記法など。エジプト象形文字、現代音楽の楽譜、数学の英数字など。
- Emojiやその他の絵文字。
- トランプ、マージャン、ドミノなどのゲーム記号。
- 日中韓の漢字で、以前の文字符号化規格に含まれなかったもの。
2. 構造型
- Cypherクエリから返すことができます。
- パラメータとして使用不可です。
- プロパティとして保存不可です。
- Cypherリテラルを使って構築不可です。
構造の種類は以下の通りです。
-
ノード
- ID
- ラベル(複数可)
- マップ (プロパティの)
ラベルは値ではなく、パターンシンタックスの一種です。
-
リレーションシップ
- ID
- タイプ
- マップ (プロパティの)
- 開始ノードのID
- 終了ノードのID
-
パス(ノードとリレーションシップの交互配列)
ノード、リレーションシップ、パスは、パターンマッチングの結果として返されます。Neo4jでは、全てのリレーションシップは方向性を持っています。しかし、クエリ時に無向性のリレーションシップの概念を持つことができます。
3. 複合型
- Cypherクエリから返すことができます。
- パラメータとして使用可能です。
- プロパティとして保存不可です。
- Cypherリテラルを使って構築可能です。
複合型の種類は以下の通りです。
-
リスト
雑多な値の順序付きコレクションです。各値は任意のプロパティ型、構造型または複合型を持ちます。 -
マップ
キーとバリュー( Key , Value )のペアの雑多な値、非順序のコレクションです。- Key はString型です。
- Value は、任意のプロパティ、構造型、または複合型を持ちます。
複合型は、null
を含むこともできます。
null
を使用する場合は、特別な注意が必要です(null
の使用を参照)。
名前付けのルールと推奨事項
本節では、ノード・ラベル、リレーションシップ・タイプ、プロパティ名、変数、インデックス、および制約の命名に関するルールと推奨事項について説明します。
1. 命名規則
-
英字
- 名前はアルファベットで始めてください。
-
å
,ä
,ö
,ü
などの「非英語」文字が含まれます。
-
数字
- 名前は数字で始めてはいけません。
- 例として、
1first
はダメですが、first1
はOKです。
-
記号
- 名前に記号を含めることはできません。ただし、
my_variable
のようにアンダースコアを使用する場合と、$myParam
のように$
を最初の文字として使用してパラメータを表す場合は例外です。
- 名前に記号を含めることはできません。ただし、
-
長さ
- Neo4jのバージョンにより、
65535
(2^16 - 1)
字または65534
字までと非常に長くすることができます。
- Neo4jのバージョンにより、
-
大文字と小文字の区別
- 名前は大文字と小文字を区別します。したがって、
:PERSON
,:Person
,:person
は3つの異なるラベルであり、n
とN
は2つの異なる変数となります。
- 名前は大文字と小文字を区別します。したがって、
-
スペース
- 先頭と末尾のスペースは自動的に削除されます。例えば、
MATCH ( a ) RETURN a
は、MATCH (a) RETURN a
と同じ意味です。
- 先頭と末尾のスペースは自動的に削除されます。例えば、
数字、記号、空白文字を含む非英字を名前に使用することができますが、バッククオート(`)を使用してエスケープする必要があります。例えば、`^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)
- 以下のクエリは、ノードとリレーションシップの両方が a という名前を持っているため無効です。
3. 推奨される命名規則
以下は推奨される命名規則です。
項目 | 命名規則 | 例 |
---|---|---|
ノードのラベル | パスカルケース | ×:vehicle_owner 〇: :VehicleOwner
|
リレーションシップのタイプ | スネークケース 全て大文字 |
×:ownsVehicle 〇: :OWNS_VEHICLE
|
式
本節では、Cypherの式の概要と例を説明します。
1. 一般的な式
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種類があります。
CASEはRETURNやWITHの一部としてのみ使用でき、その結果を後続の句や文で使用することができます。
3.1. 単純なCASE式:複数の値に対する式の比較
式は計算され、一致するものが見つかるまでWHEN
句と順番に比較されます。一致するものがない場合、ELSE
句の式が返される。ただし、ELSE
句がなく、一致するものが見つからない場合は、null
が返されます。
注:要はtest
の値がvalue
ならばresult
を戻します。同様に他のWHEN
以降と比較していき、一致するものが全く無ければ default
を戻します。
構文
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE default]
END
引数
名前 | 説明 |
---|---|
test |
有効な式 |
value |
結果がtest と比較される式 |
result |
test がvalue と一致した場合に出力として返される式 |
default |
何もマッチしない場合、default が返されます |
クエリ
MATCH (n)
RETURN
CASE n.eyes
WHEN 'blue' THEN 1
WHEN 'brown' THEN 2
ELSE 3
END AS result
表1. 結果
result |
---|
2 1 3 2 1
|
Rows: 5 |
3.2. 一般的なCASE形式:複数の条件式を表現可能
述語は、true
値が見つかるまで順に評価され、その結果値が使われます。一致するものがない場合は、ELSE
句内の式が戻されます。しかし、ELSE
句がなく、マッチするものが見つからなければ、null
が戻されます。
構文
CASE
WHEN predicate THEN result
[WHEN ...]
[ELSE default]
END
引数
名前 | 説明 |
---|---|
predicate |
有効な選択肢を見つけるためにテストされる述語 |
result |
predicate がtrue と評価された場合に出力として返される式 |
default |
何もマッチしない場合、default が返されます |
クエリ
MATCH (n)
RETURN
CASE
WHEN n.eyes = 'blue' THEN 1
WHEN n.age < 40 THEN 2
ELSE 3
END AS result
表2. 結果
result |
---|
2 1 3 3 1
|
Rows: 5 |
3.3. 単純なCASEと一般的なCASEの使い分け
2つの式の構文は非常に似ているため、どちらの式を使用すべきかわからない場合があります。このシナリオを次のクエリで説明します。このクエリではn.age
がnull
の場合、age_10_years_ago
は-1
であることが期待されています。
クエリ
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" "Bob" "Charlie" "Daniel" "Eskil"
|
28 15 43 <null> 31
|
Rows: 5 |
期待通りの動作をする修正されたクエリは、以下の一般的なCASE
式で与えられます。
クエリ
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" "Bob" "Charlie" "Daniel" "Eskil"
|
28 15 43 -1 31
|
Rows: 5 |
3.4. CASEの結果を後続の節または文に使用する
CASE
の結果を使用して、ノードまたはリレーションシップにプロパティを設定することができます。例えば、ノードを直接指定する代わりに、式で選択されたノードのプロパティを設定することができます。
クエリ
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を参照してください。
表5. 結果
(empty result) |
---|
Rows: 0 Properties set: 5 |
変数
本節では、Cypherにおける変数の概要を説明します。
パターンやクエリの一部を参照するとき、名前を付けて参照します。その名前を変数と呼びます。
この例では、
MATCH (n)-->(b)
RETURN b
変数はn
とb
です。
変数の命名に関する情報は、こちらを参照して下さい。
変数は、同じクエリの中でしか見ることができません。
変数は後続のクエリに持ち越されません。複数の問い合わせ部分がWITH
によって連結されている場合、変数は次の部分に引き継がれるようにWITH
句にリストアップされなければなりません。詳しくはWITHを参照してください。
予約語
本節では、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
パラメータ
本節では、パラメータ化クエリを説明します。
1. はじめに
Cypherはパラメータを使った問い合わせをサポートしています。パラメータ化クエリとは、パラメータにプレースホルダを使用し、実行時にパラメータ値を与えるクエリのことです。これは、開発者がクエリを作成するために文字列を構築する必要がないことを意味します。さらに、Cypherでは、パラメータによって実行プランのキャッシュが容易になり、クエリの実行時間が短縮されます。
パラメータを使用できるのは以下です。
- リテラルと式
- ノードとリレーションシップのID
パラメータは、以下の構成要素には使用できません。これらは、クエリプランにコンパイルされるクエリ構造の一部を形成するためです。
- プロパティキー。したがって、
MATCH (n) WHERE n.$param = 'something'
は無効です。 - リレーションシップタイプ
- ラベル
パラメータは、文字と数字、およびこれらの任意の組み合わせで構成することができますが、数字や通貨記号で始めることはできません。
クエリ実行時のパラメータの設定はクライアント環境に依存します。例えば、
- Cypher Shellでパラメータを設定するには、
:param name => 'Joe'
とします。詳細は、操作マニュアル → Cypher Shell - クエリパラメータ を参照してください。 - Neo4jブラウザの場合は、Cypher Shellと同じ構文で、
:param name => 'Joe'
とします。 - ドライバを使用する場合、構文は言語に依ります。Neo4jドライバのマニュアルの Transactions にある例を参照してください。
- Neo4j HTTP API を使用する場合は、HTTP APIのドキュメントを参照してください。
以下に、パラメータの使用例の一覧を示します。これらの例では、パラメータはJSONで与えられます。パラメータをどのように送信するかは、使用するドライバに依存します。
古いパラメータ構文である{param}
はNeo4j 3.0で非推奨となり、Neo4j 4.0で完全に削除されました。これを使用すると、シンタックスエラーが発生します。しかし、クエリの前にCYPHER 3.5
を付けると、警告は出ますが、まだ使用することは可能です。詳しくはCypher互換性を参照してください。
2. 自動パラメータ化
クエリがパラメータを使用しない場合、Cypherはとにかくパラメータを推論しようとします。クエリ内の各リテラルは、パラメータに置き換えられます。これにより、リテラル以外は同一の問い合わせに対して、計算された計画の再利用性を高めることができます。この動作に依存することはお勧めしません。ユーザは適切と思われるところでパラメータを使用すべきです。
少なくとも1つのパラメータがクエリで使用されている場合、そのクエリでは自動パラメータ化は行われません。これは、残りのリテラルがパラメータに変換されないことを意味します。
3. 文字列リテラル
パラメータ
{
"name" : "Johan"
}
クエリ
MATCH (n:Person)
WHERE n.name = $name
RETURN n
この構文では、パラメータも使用できます。
パラメータ
{
"name" : "Johan"
}
クエリ
MATCH (n:Person {name: $name})
RETURN n
4. 正規表現
パラメータ
{
"regex" : ".*h.*"
}
クエリ
MATCH (n:Person)
WHERE n.name =~ $regex
RETURN n.name
5. 大文字小文字を区別した文字列パターンマッチング
パラメータ
{
"name" : "Michael"
}
クエリ
MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name
6. プロパティを持つノードの作成
パラメータ
{
"props" : {
"name" : "Andy",
"position" : "Developer"
}
}
クエリ
CREATE ($props)
7. プロパティを持つ複数のノードの作成
パラメータ
{
"props" : [ {
"awesome" : true,
"name" : "Andy",
"position" : "Developer"
}, {
"children" : 3,
"name" : "Michael",
"position" : "Developer"
} ]
}
クエリ
UNWIND $props AS properties
CREATE (n:Person)
SET n = properties
RETURN n
8. ノード上の全てのプロパティを設定する
これは、現在のプロパティを全て置き換えることに注意してください。
パラメータ
{
"props" : {
"name" : "Andy",
"position" : "Developer"
}
}
クエリ
MATCH (n:Person)
WHERE n.name = 'Michaela'
SET n = $props
9. SKIPとLIMIT
パラメータ
{
"s" : 1,
"l" : 1
}
クエリ
MATCH (n:Person)
RETURN n.name
SKIP $s
LIMIT $l
10. ノードID
パラメータ
{
"id" : 0
}
クエリ
MATCH (n)
WHERE id(n) = $id
RETURN n.name
11. 複数のノードID
パラメータ
{
"ids" : [ 0, 1, 2 ]
}
クエリ
MATCH (n)
WHERE id(n) IN $ids
RETURN n.name
12. プロシージャの呼び出し
パラメータ
{
"indexname" : "My index"
}
クエリ
CALL db.resampleIndex($indexname)
演算子
本節では、演算子の概要を説明します。
1.演算子の一覧
演算子名 | 演算子 |
---|---|
集計演算子 | DISTINCT |
プロパティ演算子 | 静的プロパティアクセスの場合は. 動的プロパティアクセスの場合は [] 全てのプロパティを置換する場合は = 特定のプロパティを変更する場合は +=
|
数学演算子 |
+ , - , * , / , % , ^
|
比較演算子 |
= , <> , < , > , <= , >= , IS NULL , IS NOT NULL
|
文字列固有の比較演算子 |
STARTS WITH , ENDS WITH , CONTAINS , =~ (正規表現用) |
ブール演算子 |
AND , OR , XOR , NOT
|
文字列演算子 |
+ (連結) |
時間演算子 | 継続時間と一時インスタンス/継続時間の間の演算には+ と- 継続時間と数値の間の演算には * と/
|
マップ演算子 | キーによる静的な値アクセスの場合は. 、キーによる動的な値アクセスの場合は[]
|
リスト演算子 |
+ (連結)IN (リスト内のエレメントの存在をチェック)[] (エレメントに動的にアクセス) |
2. 集計演算子
集計演算子は次のもので構成されます。
- 重複値の削除:
DISTINCT
2.1.DISTINCT演算子の使用
Person
ノードから一意の目の色を取得します。
クエリ
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" "brown"
|
Rows: 2 Nodes created: 3 Properties set: 6 Labels added: 3 |
DISTINCT
は通常、集計関数と組み合わせて使用されます。
3.プロパティ演算子
プロパティ演算子はノードまたはリレーションシップに関連し、次のもので構成されます。
- ドット演算子
.
ノードまたはリレーションシップのプロパティに静的にアクセスします。 - サブスクリプト演算子
[]
ノードまたはリレーションシップのプロパティに動的にアクセスします。 - プロパティ置換演算子
=
ノードまたはリレーションシップのすべてのプロパティを置き換えます。 - プロパティ変換演算子
+=
ノードまたは関係の特定のプロパティを設定します。
3.1. .演算子を使用してノードまたはリレーションシップのプロパティに静的にアクセスする
クエリ
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" "Tom"
|
Rows: 2 Nodes created: 2 Properties set: 4 Labels added: 2 |
3.2. []演算子を使用した動的に計算されたプロパティキーのフィルタリング
クエリ
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 Nodes created: 4 Properties set: 8 Labels added: 4 |
動的プロパティアクセスの詳細については、基本的な使い方を参照してください。
null
に関する[]
演算子の動作については、ここで詳しく説明します。
3.3. =演算子を使用したノードまたはリレーションシップのすべてのプロパティの置換
クエリ
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 Nodes created: 1 Properties set: 5 Labels added: 1 |
プロパティ置換演算子=
の使用方法の詳細は、マップと=
を使用してすべてのプロパティを置換するを参照してください。
3.4. +=演算子を使用してノードまたはリレーションシップの特定のプロパティを変更する
クエリ
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 Nodes created: 1 Properties set: 4 Labels added: 1 |
プロパティ変換演算子+=
の使用方法の詳細については、「マップと+=を使用して特定のプロパティを変換する」を参照してください。
4. 数学演算子
算術演算子は次のもので構成されます。
- 加算:
+
- 減算または単項マイナス:
-
- 乗算:
*
- 除算:
/
- 剰余:
%
- 累乗:
^
4.1. 指数演算子^を使用する
クエリ
WITH 2 AS number, 3 AS exponent
RETURN number ^ exponent AS result
表6. 結果
result |
---|
8.0 |
Rows: 1 |
4.2. 単項マイナス演算子の使用-
クエリ
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つの数値の比較
クエリ
WITH 4 AS one, 3 AS two
RETURN one > two AS result
表8. 結果
result |
---|
true |
Rows: 1 |
比較演算子の動作の詳細は、「値の等価と比較」を参照してください。また、これらの使用例は、「範囲の使用」を参照してください。
5.3. STARTS WITHを使用した名前のフィルタリング
クエリ
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" "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。
-
Duration 値は、全ての要素を次のように正規化して順序付けられます:全ての年は
-
- 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
の前に順序付けられるためです。
-
複合型(マップやリストなど)では、コンテナの要素はペアで比較されて順序が決定されるため、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
は(エレガントではないでしょうが)完全に合法であることに注意してください。
次に例を示します。
MATCH (n) WHERE 21 < n.age <= 30 RETURN n
これは以下と等価です。
MATCH (n) WHERE 21 < n.age AND n.age <= 30 RETURN n
したがって、ageが21~30の全てのノードと一致します。
この構文は、全ての等号=
と不等号<>
の比較、および3つより長い連鎖に拡張されます。
=
と<>
の連鎖は、Cypherでは特別な方法で扱われます。
つまり、1=1=true
は1=1 AND 1=true
と等価であり、(1=1)=true
や1=(1=true)
とは等価ではありません。
次に例を示します。
a < b = c <= d <> e
これは以下と等価です。
a < b AND b = c AND c <= d AND d <> e
6.=~とともに正規表現を使用して単語をフィルタする
クエリ
WITH ['mouse', 'chair', 'door', 'house'] AS wordlist
UNWIND wordlist AS word
WITH word
WHERE word =~ '.*ous.*'
RETURN word
表10.結果
word |
---|
"mouse" "house"
|
Rows: 2 |
フィルタリングにおける正規表現の使用に関する詳細と例は、正規表現を参照してください。
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. ブール演算子を使用した数値のフィルタ
クエリ
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 7 9
|
Rows: 3 |
8. 文字列演算子
文字列演算子には次のものがあります。
- 文字列の連結:
+
8.1. 2つの文字列を+で連結する
クエリ
RETURN 'neo' + '4j' AS result
表12. 結果
結果 |
---|
"neo4j" |
Rows: 1 |
9. 時間演算子
時間演算子には次のものがあります。
-
時間のインスタントまたは別の期間に期間を追加する:
+
- 時間のインスタントまたは別の期間から期間を差し引く:
-
- 期間に数値を掛ける:
*
- 期間を数値で除算する:
/
次の表は、演算とオペランドタイプの組み合わせごとに、各時間演算子のアプリケーションから返される値のタイプを示しています。
演算子 | 左側のオペランド | 右側のオペランド | 結果のタイプ |
---|---|---|---|
+ ■
|
時間のインスタント | 期間 | 時間のインスタント |
+ ■
|
期間 | 時間のインスタント | 時間のインスタント |
- ■
|
時間のインスタント | 期間 | 時間のインスタント |
+ ■
|
期間 | 期間 | 期間 |
- ■
|
期間 | 期間 | 期間 |
* ■
|
期間 | 数字 | 期間 |
* ■
|
数字 | 期間 | 期間 |
/ ■
|
期間 | 数字 | 期間 |
9.1. 時間のインスタントと期間との加減算
クエリ
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 |