検索を行いたいのですが、2つのラベル(OR条件)からトラバースを開始したいと思います。たとえば、ラベルが 'Male'または 'Female'で、そのプロパティがname =〜 '.ail。'であるすべてのノードを見つける必要があります。
それをWHERE
句に入れることができます:
MATCH n
WHERE n:Male OR n:Female
RETURN n
[〜#〜] edit [〜#〜]
@tbaumが指摘しているように、これはAllNodesScan
を実行します。ラベルがかなり新しいときに答えを書き、クエリプランナーが最終的に各ラベルにNodeByLabelScan
を使用して実装することを期待しました。
MATCH n
WHERE n:Male
RETURN n
私はまだこれがクエリの合理的な表現であり、クエリプランナがラベルスキャンで実装することを期待するのが合理的であると思いますが、Neo4j 2.2.3の時点でクエリはAllNodesScan
とラベルフィルター。したがって、これはより冗長な代替案です。ラベルの選言は集合の集合を意味し、この集合はさまざまな方法で表現できるため、クエリプランナーがすべてのノードをスキャンせずに実装し、代わりにラベルごとにNodeByLabelScan
で始まるように表現できます。
MATCH (n:Male)
WHERE n.name =~ '.ail.'
RETURN n
UNION MATCH (n:Female)
WHERE n.name =~ '.ail.'
RETURN n
つまり、ラベルごとにクエリを1回表現し、明示的なUNION
で結合します。少なくともラベルの数が少ない場合、これは不合理ではありませんが、クエリプランナーが単純なクエリから同じ実装を推論できない理由が明確ではないため、github問題を開きました ここ 。
MATCH n WHERE n:Label1 OR n:Label2
... AllNodesScanになりますが、これは悪い考えです!
おそらくより良い解決策:
OPTIONAL MATCH (n1:Label1)
WITH collect(distinct n1) as c1
OPTIONAL MATCH (n2:Label2)
WITH collect(distinct n2) + c1 as c2
OPTIONAL MATCH (n3:Label3)
WITH collect(distinct n3) + c2 as c3
UNWIND c3 as nodes
RETURN count(nodes),labels(nodes)
Neo4j 3.4.7では、クエリプランナーは、2つのORされたラベルフィルターを使用してWHEREクエリを渡すと、UNIONを実行し、次に2 NodeByLabelScan
sのDISTINCTを実行します。 sandbox Offshore Leaks Database with EXPLAIN MATCH (o) WHERE o:Officer OR o:Entity RETURN o
を試すと、次の計画が得られます。