什么 Cypher 查询来检索 Neo4J 中某些节点之间的关系?
What Cypher query to retrieve the relations of certain nodes to each other in Neo4J?
TL:DR:
我需要找到最有效的 Cypher 查询,它将节点连接到具有特定类型关系的特定节点类型,然后检索这些节点之间的连接,过滤掉前 150 个最连接的节点,并将它们展示给用户。
我在下面提出了一个使用 APOC 关系 属性 查询的建议,但我认为它可以变得更有效率,所以我正在寻求您的建议。
详细说明:
在我的数据模型中,我有以下类型的节点:
:Concept
:Context
:User
:Statement
这个是用来做文本网络分析的,所以基本思路是:Statements
中出现的属于某个:Context
的:Concepts
是由某个[=14=添加的] ].
它们也有属性,例如 uid
(唯一 ID)和 name
(名称)。
每个 :Concept
都以 :TO
类型的定向关系连接到每个其他 :Concept
。
如果 :Concept
属于 :Context
,它与 :Context
有 :AT
关系
如果 :Concept
是由 :User
创建的,则它与具有 :BY
关系类型的用户相关联。
我还为关系添加了属性,以便它们显示哪个用户建立了 :TO
连接以及它们出现在哪个上下文中。
我需要获取特定上下文中的节点列表及其关系,因此我目前使用类型的 Cypher / APOC 查询:
CALL apoc.index.relationships('TO','user:15229100-b20e-11e3-80d3-6150cb20a1b9')
YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
AND (ctx.name="decon" )
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
它工作得很好,但是,问题是如果图很大(例如超过 1000 个节点和 5000 个连接),查询它需要很长时间。
所以我希望能够过滤我得到的关系数。
使用上面的请求很难做到,因为我想过滤掉前 150 个连接最多的节点,我需要先获取数据才能做到这一点。
所以我想也许我应该改变我的请求的逻辑,而不是:
1) 查询我感兴趣的:Context
;
2) 获取与之相连的所有:Concept
个节点;
3) 找到检索到的:Concept
个节点之间的所有关系;
4) 获取前 X (150) 个最连接的 :Concept
个节点,忽略其余的。
5) 将它们展示给用户。
我尝试了以下查询:
MATCH (ctx:Context{name:'decon',by:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
WITH ctx MATCH (c1:Concept)-[:AT]->(ctx),
(c2:Concept)-[:AT]->(ctx)
WITH c1, c2
MATCH (c1)-[rel:TO]->(c2)
RETURN DISTINCT rel;
但似乎需要更长的时间。
我还需要过滤掉那些节点之间的关系,让它们只显示某个:User
建立的关系,只出现在某个:Statement
.
有人知道我还能尝试什么吗?
PS
源代码在 https://github.com/noduslabs/infranodus/blob/master/lib/entry.js#L573
您正在生成那些 :Concept 节点的笛卡尔积,这会减慢您的查询速度。
您可以试试这个:
MATCH (c:Concept)-[:AT]->(:Context{name:'decon',by:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
WHERE (c)-[:BY]->(:User {uid:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
// AND <additional predicate for desired :Statement>
WITH collect(c) as concepts
UNWIND concepts as c
WITH c, size([(c)-[:TO]->(c2) WHERE c2 in concepts | c2]) as connections
ORDER BY connections DESC
LIMIT 150
RETURN c
您当然需要 :Context(by) 上的索引以便快速进行初始匹配。
TL:DR:
我需要找到最有效的 Cypher 查询,它将节点连接到具有特定类型关系的特定节点类型,然后检索这些节点之间的连接,过滤掉前 150 个最连接的节点,并将它们展示给用户。
我在下面提出了一个使用 APOC 关系 属性 查询的建议,但我认为它可以变得更有效率,所以我正在寻求您的建议。
详细说明:
在我的数据模型中,我有以下类型的节点:
:Concept
:Context
:User
:Statement
这个是用来做文本网络分析的,所以基本思路是:Statements
中出现的属于某个:Context
的:Concepts
是由某个[=14=添加的] ].
它们也有属性,例如 uid
(唯一 ID)和 name
(名称)。
每个 :Concept
都以 :TO
类型的定向关系连接到每个其他 :Concept
。
如果 :Concept
属于 :Context
,它与 :Context
:AT
关系
如果 :Concept
是由 :User
创建的,则它与具有 :BY
关系类型的用户相关联。
我还为关系添加了属性,以便它们显示哪个用户建立了 :TO
连接以及它们出现在哪个上下文中。
我需要获取特定上下文中的节点列表及其关系,因此我目前使用类型的 Cypher / APOC 查询:
CALL apoc.index.relationships('TO','user:15229100-b20e-11e3-80d3-6150cb20a1b9')
YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
AND (ctx.name="decon" )
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
它工作得很好,但是,问题是如果图很大(例如超过 1000 个节点和 5000 个连接),查询它需要很长时间。
所以我希望能够过滤我得到的关系数。
使用上面的请求很难做到,因为我想过滤掉前 150 个连接最多的节点,我需要先获取数据才能做到这一点。
所以我想也许我应该改变我的请求的逻辑,而不是:
1) 查询我感兴趣的:Context
;
2) 获取与之相连的所有:Concept
个节点;
3) 找到检索到的:Concept
个节点之间的所有关系;
4) 获取前 X (150) 个最连接的 :Concept
个节点,忽略其余的。
5) 将它们展示给用户。
我尝试了以下查询:
MATCH (ctx:Context{name:'decon',by:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
WITH ctx MATCH (c1:Concept)-[:AT]->(ctx),
(c2:Concept)-[:AT]->(ctx)
WITH c1, c2
MATCH (c1)-[rel:TO]->(c2)
RETURN DISTINCT rel;
但似乎需要更长的时间。
我还需要过滤掉那些节点之间的关系,让它们只显示某个:User
建立的关系,只出现在某个:Statement
.
有人知道我还能尝试什么吗?
PS 源代码在 https://github.com/noduslabs/infranodus/blob/master/lib/entry.js#L573
您正在生成那些 :Concept 节点的笛卡尔积,这会减慢您的查询速度。
您可以试试这个:
MATCH (c:Concept)-[:AT]->(:Context{name:'decon',by:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
WHERE (c)-[:BY]->(:User {uid:'15229100-b20e-11e3-80d3-6150cb20a1b9'})
// AND <additional predicate for desired :Statement>
WITH collect(c) as concepts
UNWIND concepts as c
WITH c, size([(c)-[:TO]->(c2) WHERE c2 in concepts | c2]) as connections
ORDER BY connections DESC
LIMIT 150
RETURN c
您当然需要 :Context(by) 上的索引以便快速进行初始匹配。