1. HOME
  2. ブログ
  3. テクノロジー
  4. Neo4j
  5. OPTIONAL MATCH 句直後のWHERE句の意味は?

BLOG

ブログ

Neo4j

OPTIONAL MATCH 句直後のWHERE句の意味は?

Neo4jのcypher文の話です。例えば、つぎのようなテストデータがあったとします。

// create data
WITH RANGE(1,5) AS ages
UNWIND ages AS age CREATE(k:Kid{age:age}) RETURN k
;
MATCH(ks:Kid) WHERE ks.age > 2
WITH COLLECT(ks) AS ks
UNWIND ks AS k
FOREACH (n IN RANGE(1, k.age) | CREATE(k)-[:HAS]->(t:Toy{size:n}))
;

// show all data
MATCH(k:Kid)
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) RETURN *;

// delete all data
MATCH(k:Kid)
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) DETACH DELETE k, t RETURN *;

テストデータに対して、以下のような3つのクエリを投げてみる。

MATCH(k:Kid) // query No.1
WITH k
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) WHERE t.size = 4
WITH k
WHERE t.size = 4
RETURN COUNT(DISTINCT k);
=> 2件

MATCH(k:Kid) // query No.2
WITH k
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) WHERE t.size IS NOT NULL
WITH k
WHERE t.size IS NOT NULL
RETURN COUNT(DISTINCT k);
=> 3件

MATCH(k:Kid) // query No.3
WITH k
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) WHERE t.size IS NULL
WITH k
WHERE t.size IS NULL
RETURN COUNT(DISTINCT k);
=> 5件

上記の結果について、No.1とNo.2については問題ない(予想通りの結果である)が、No.3は5件ではなく2件が正しいのではないかとずっと訝っていた。
なぜ5件になるかの理由が分からないのでStackoverflowに質問してみた。
そこで分かったことを以下に記す。

まず、大前提。
・OPTIONAL MATCHは全てのKidノードを返却する。
そして、
・WHERE句にマッチするToyノードはそのノードを、そうでなければnullを返却する。
以下は、想定通り。

MATCH(k:Kid) // query No.1
WITH k
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) WHERE t.size = 4
RETURN k.age, t.size;
⇒
k.age	t.size
1	null
2	null
3	null
4	4
5	4

では、以下は?

MATCH(k:Kid) // query No.1
WITH k
OPTIONAL MATCH(k:Kid)-[:HAS]->(t:Toy) WHERE t.size IS NULL
RETURN k.age, t.size;
⇒
k.age	t.size
1	null // 実際にt.sizeがnullのもの
2	null // 同上
3	null // t.sizeはnullではないが、WHERE句にマッチしないので、nullが返されている
4	null // 同上
5	null // 同上

要するに、上記のように、同じnullでも2つの種類(意味合いの違い)があるということです。

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

関連記事