Neo4j匹配与集合中所有节点相关的节点 [英] Neo4j match nodes related to all nodes in collection

查看:391
本文介绍了Neo4j匹配与集合中所有节点相关的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a graph of tags, which are related with each other. My goal is to create a Cypher query, which will return all tags that are related to an array of input tags via 1 or 2 hops.

我进行了查询,该查询无法正常工作.

I made a query, which doesn't work quite as intended.

MATCH (t:Tag)
WHERE t.name IN ["A", "B", "C"]
WITH t
MATCH (a:Tag)-[:RELATED*1..2]-(t)
RETURN DISTINCT a;

此查询首先找到节点ABC,然后通过1搜索与AB C相关的标签节点或更少.

This query first finds the nodes A, B, C and then searches for tags, that are related to A, B or C via 1 node or less.

我想做的是找到与所有三个节点(AB C)相关的标签.

What I want to do though is to find tags, which are related to ALL three nodes (A, B and C).

我知道我可以连接MATCHWITH语句,并执行以下操作:

I know I could concatenate MATCH and WITH statements, and do something like this:

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个输入标签:ABC),它的运行速度会非常缓慢.

But it runs painfully slow, when the number of input tags increase (in this case only 3 input tags: A, B, C).

有没有办法像我第一次尝试一样在一个查询中做到这一点?

So is there a way to make it in one query, similar to my first try?

推荐答案

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

Here is a solution that only requires a single MATCH clause.

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)相关"(最多2个步骤)的所有标签(other).
  • 然后使用聚合为每个t收集 distinct other个节点.在此示例中,我们最终得到3个others集合-每个t 1个.
  • 然后将所有others集合收集到单个coll集合中.
  • 最后,由于结果集应该是每个others集合的交集,因此查询将遍历第一个others集合中的节点,并提取出其余others集合中的节点.而且,由于每个others集合已经包含不同的节点,因此结果还必须具有不同的节点.
    • The query finds all the tags (other) that are "related" (by up to 2 steps) to each of your named tags (t).
    • It then uses aggregation to collect the distinct other nodes for each t. In this example, we end up with 3 others collections -- 1 for each t.
    • It then collects all the others collections into a single coll collection.
    • Finally, since the result set is supposed to be the intersection of every others collection, the query walks through the nodes in first others collection, and extracts the ones that are also in the remaining others collections. And, since each others collection already contains distinct nodes, the result must also have distinct nodes.
    • 此外,如果您有很多标签,可以通过以下方法使上述查询更快一些:

      In addition, if you have a lot of tags, the above query can be made a bit faster by:

      1. 创建索引(或唯一性约束,它会自动在:Tag(name)上为您创建一个索引,然后
      2. 通过在MATCHWHERE子句之间插入以下子句来指定在查询中使用该索引.目前,Cypher引擎不会针对该特定查询自动使用索引.

      1. Creating an index (or uniqueness constraint, which automatically creates an index for you) on :Tag(name), and then
      2. Specifying the use of that index in your query -- by inserting the following clause between the MATCH and WHERE clauses. Currently, the Cypher engine does not automatically use the index for this specific query.

      USING INDEX t:Tag(name)
      

      这篇关于Neo4j匹配与集合中所有节点相关的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆