什么Cypher查询可检索Neo4J中某些节点之间的关系?

时间:2019-01-01 20:53:34

标签: neo4j cypher neo4j-apoc

TL:DR:

我需要找到最高效的Cypher查询,该查询将使具有特定关系类型的节点连接到特定节点类型,然后检索这些节点之间的连接,筛选出连接最紧密的150个节点,并显示他们给用户。

我在下面提出了一个使用APOC关系属性查询的方法,但是我认为它可以提高效率,因此我正在寻找您的建议。

长期解释:

在我的数据模型中,我有以下类型的节点:

:Concept :Context :User :Statement

这用于文本网络分析,因此基本思想是:Concepts出现在:Statements中,属于由某个:Context添加的某个:User

它们还具有属性,例如uid(唯一ID)和name(名称)。

每个:Concept都以:Concept类型的有向关系连接到其他:TO

如果:Concept属于:Context,则它与该:AT具有:Context关系

如果: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

1 个答案:

答案 0 :(得分:2)

您正在生成这些: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)上建立索引,以便快速进行初始匹配。