Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j匹配与集合中所有节点相关的节点_Neo4j_Cypher - Fatal编程技术网

Neo4j匹配与集合中所有节点相关的节点

Neo4j匹配与集合中所有节点相关的节点,neo4j,cypher,Neo4j,Cypher,我有一个标签图,它们相互关联。我的目标是创建一个Cypher查询,它将通过1或2跳返回与输入标记数组相关的所有标记 我提出了一个问题,但没有达到预期效果 MATCH (t:Tag) WHERE t.name IN ["A", "B", "C"] WITH t MATCH (a:Tag)-[:RELATED*1..2]-(t) RETURN DISTINCT a; 此查询首先查找节点A、B、C,然后通过1个或更少的节点搜索与A、B或C相关的标记 不过我想做的是找到与所有三个节点(A、B和C)相关

我有一个标签图,它们相互关联。我的目标是创建一个Cypher查询,它将通过1或2跳返回与输入标记数组相关的所有标记

我提出了一个问题,但没有达到预期效果

MATCH (t:Tag)
WHERE t.name IN ["A", "B", "C"]
WITH t
MATCH (a:Tag)-[:RELATED*1..2]-(t)
RETURN DISTINCT a;
此查询首先查找节点
A
B
C
,然后通过1个或更少的节点搜索与
A
B
C
相关的标记

不过我想做的是找到与所有三个节点(
A
B
C
)相关的标记


我知道我可以用语句连接
匹配
,并执行如下操作:

MATCH (t:Tag)-[:RELATED*1..2]-(a:Tag)
WHERE t.name="A"

WITH DISTINCT a
MATCH (t:Tag)-[:RELATED*1..2]-(a)
WHERE t.name="B"

WITH DISTINCT a
MATCH (t:Tag)-[:RELATED*1..2]-(a)
WHERE t.name="C"
...
RETURN DISTINCT a;
但是,当输入标记的数量增加时,它运行得非常慢(在这种情况下,只有3个输入标记:
A
B
C


那么,有没有一种方法可以在一个查询中实现它,类似于我的第一次尝试?

这个如何:

MATCH (t:Tag)-[:RELATED*1..2]-(other:Tag)
WHERE t.name IN ["A", "B", "C"] 
WITH t, collect(other.name) as others
WHERE ALL(x in ["A","B","C"] WHERE x in others)
RETURN t
诀窍是将
t
的所有相关节点放入一个集合(其他)中,并使用
all
谓词确保所有的a、B和C都是该集合的一部分。

这个怎么样:

MATCH (t:Tag)-[:RELATED*1..2]-(other:Tag)
WHERE t.name IN ["A", "B", "C"] 
WITH t, collect(other.name) as others
WHERE ALL(x in ["A","B","C"] WHERE x in others)
RETURN t

诀窍是将
t
的所有相关节点放入一个集合(其他)中,并使用
all
谓词确保所有a、B和C都是该集合的一部分。

这里有一个解决方案,它只需要一个
匹配
子句

MATCH (t:Tag)-[:RELATED*..2]-(other:Tag)
WHERE t.name IN ["A", "B", "C"]
WITH t, COLLECT(DISTINCT other) AS others
WITH COLLECT(others) AS coll
RETURN FILTER(x IN coll[0] WHERE ALL(y IN coll[1..] WHERE x IN y)) AS res;
  • 查询将查找与每个命名标记(
    t
    )相关(最多两步)的所有标记(
    other
  • 然后,它使用聚合为每个
    t
    收集不同的
    其他
    节点。在本例中,我们最终得到了3个
    others
    集合——每个
    t
    集合1个
  • 然后,它将所有
    others
    集合收集到单个
    coll
    集合中
  • 最后,由于结果集应该是每个
    others
    集合的交集,因此查询遍历第一个
    others
    集合中的节点,并提取其余
    others
    集合中的节点。而且,由于每个
    others
    集合已经包含不同的节点,因此结果也必须具有不同的节点
此外,如果您有很多标记,可以通过以下方式加快上述查询:

  • (或,它会自动为您创建索引)在
    :Tag(name)
    ,然后
  • 在查询中指定该索引的使用——在
    MATCH
    WHERE
    子句之间插入以下子句。目前,Cypher引擎不会自动将索引用于此特定查询

    USING INDEX t:Tag(name)
    

  • 这里是一个只需要一个
    MATCH
    子句的解决方案

    MATCH (t:Tag)-[:RELATED*..2]-(other:Tag)
    WHERE t.name IN ["A", "B", "C"]
    WITH t, COLLECT(DISTINCT other) AS others
    WITH COLLECT(others) AS coll
    RETURN FILTER(x IN coll[0] WHERE ALL(y IN coll[1..] WHERE x IN y)) AS res;
    
    • 查询将查找与每个命名标记(
      t
      )相关(最多两步)的所有标记(
      other
    • 然后,它使用聚合为每个
      t
      收集不同的
      其他
      节点。在本例中,我们最终得到了3个
      others
      集合——每个
      t
      集合1个
    • 然后,它将所有
      others
      集合收集到单个
      coll
      集合中
    • 最后,由于结果集应该是每个
      others
      集合的交集,因此查询遍历第一个
      others
      集合中的节点,并提取其余
      others
      集合中的节点。而且,由于每个
      others
      集合已经包含不同的节点,因此结果也必须具有不同的节点
    此外,如果您有很多标记,可以通过以下方式加快上述查询:

  • (或,它会自动为您创建索引)在
    :Tag(name)
    ,然后
  • 在查询中指定该索引的使用——在
    MATCH
    WHERE
    子句之间插入以下子句。目前,Cypher引擎不会自动将索引用于此特定查询

    USING INDEX t:Tag(name)
    

  • 这里有一个替代方案:

    MATCH shortestPath((t:Tag)<-[:RELATED*1..2]-(source:Tag)) //make sure there are no duplicate paths 
    WHERE source.name IN ["A","B","C"] AND NOT source.name = t.name //shortest path for identical node would throw an exception
    WITH COLLECT(t) as tags //all tags that were reachable, with duplicates for reachable from multiple tags
    UNWIND tags as tag //for each tag
    WITH tag, tags //using with as match would be a drastic slowdown
    WHERE size(filter(t IN tags WHERE ID(t) = ID(tag))) = 3 //if it is connected to all three, it must have been matched three times
    RETURN DISTINCT m //since any match will still be in there 3 (or n) times
    

    匹配最短路径((t:Tag)这里有一个替代方案:

    MATCH shortestPath((t:Tag)<-[:RELATED*1..2]-(source:Tag)) //make sure there are no duplicate paths 
    WHERE source.name IN ["A","B","C"] AND NOT source.name = t.name //shortest path for identical node would throw an exception
    WITH COLLECT(t) as tags //all tags that were reachable, with duplicates for reachable from multiple tags
    UNWIND tags as tag //for each tag
    WITH tag, tags //using with as match would be a drastic slowdown
    WHERE size(filter(t IN tags WHERE ID(t) = ID(tag))) = 3 //if it is connected to all three, it must have been matched three times
    RETURN DISTINCT m //since any match will still be in there 3 (or n) times
    

    匹配最短路径((t:Tag)您查询的语法不正确-请看
    WHERE ALL
    语句,它没有真正的意义。仍然感谢您的尝试,我将研究
    ALL
    谓词,也许它会解决我的问题。我刚刚用正确的语句更新了我的答案。恐怕您误解了问题。我不想确定在
    A
    B
    C
    在集合中(其他),但我正试图找到同时连接到
    A
    B
    C
    的所有其他节点。因此,例如,如果节点
    D
    与所有三个输入节点都有关系,则它将位于输出中。此外,如果节点
    E
    仅连接到
    A
    A
    B
    ,B但如果不是
    C
    ,那么它就不会出现在输出中。我问题中的第二个查询实际上是有效的,并且符合我的要求,因此它应该解释我需要什么。但它不必要地复杂,我认为存在一个更简单的解决方案。仅此而已:)您查询的语法不正确-请看
    WHERE ALL
    语句,它没有真正的意义。仍然感谢您的尝试,我将研究
    ALL
    谓词,也许它会解决我的问题。我刚刚用正确的语句更新了我的答案。恐怕您误解了问题。我不想确定在
    A
    B
    C
    在集合中(其他),但我正试图找到同时连接到
    A
    B
    C
    的所有其他节点。例如,如果节点
    D
    w