Neo4j匹配与集合中所有节点相关的节点 [英] Neo4j match nodes related to all nodes in collection
问题描述
我有一个标签图,它们相互关联.我的目标是创建一个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;
此查询首先找到节点A
,B
,C
,然后通过1搜索与A
,B
或 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.
我想做的是找到与所有三个节点(A
,B
和 C
)相关的标签.
What I want to do though is to find tags, which are related to ALL three nodes (A
, B
and C
).
我知道我可以连接MATCH
和WITH
语句,并执行以下操作:
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个输入标签:A
,B
,C
),它的运行速度会非常缓慢.
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
收集 distinctother
个节点.在此示例中,我们最终得到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 eacht
. In this example, we end up with 3others
collections -- 1 for eacht
. - It then collects all the
others
collections into a singlecoll
collection. - Finally, since the result set is supposed to be the intersection of every
others
collection, the query walks through the nodes in firstothers
collection, and extracts the ones that are also in the remainingothers
collections. And, since eachothers
collection already contains distinct nodes, the result must also have distinct nodes. - 创建索引(或唯一性约束,它会自动在
:Tag(name)
上为您创建一个索引,然后 -
通过在
MATCH
和WHERE
子句之间插入以下子句来指定在查询中使用该索引.目前,Cypher引擎不会针对该特定查询自动使用索引. - Creating an index (or uniqueness constraint, which automatically creates an index for you) on
:Tag(name)
, and then Specifying the use of that index in your query -- by inserting the following clause between the
MATCH
andWHERE
clauses. Currently, the Cypher engine does not automatically use the index for this specific query.
此外,如果您有很多标签,可以通过以下方法使上述查询更快一些:
In addition, if you have a lot of tags, the above query can be made a bit faster by:
USING INDEX t:Tag(name)
这篇关于Neo4j匹配与集合中所有节点相关的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!