【问题标题】:What Cypher query to retrieve the relations of certain nodes to each other in Neo4J?在 Neo4J 中检索某些节点之间的关系的 Cypher 查询是什么?
【发布时间】:2019-01-01 20:53:33
【问题描述】:

TL:DR:

我需要找到最有效的 Cypher 查询,该查询将节点连接到具有特定类型关系的特定节点类型,然后检索这些节点之间的连接,过滤掉前 150 个连接最多的节点,并显示他们给用户。

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

详细说明:

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

:Concept:Context:User:Statement

这是用于文本网络分析的,所以基本思路是:Statements中出现的:Statements中属于某个:Context被某个:User添加。

它们还具有属性,例如 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中。

有人知道我还能尝试什么吗?

附言 源代码在https://github.com/noduslabs/infranodus/blob/master/lib/entry.js#L573

【问题讨论】:

    标签: neo4j cypher neo4j-apoc


    【解决方案1】:

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

    【讨论】:

    • 谢谢!这个查询似乎很好,虽然它仍然比上面的查询要长一点(我有索引),但它的方向是正确的。我想问你:这里的这部分是什么意思:` WHERE c2 in concept | c2`垂直斜线?谢谢!
    • 在那一行中,我们使用pattern comprehension 匹配一个模式并将该模式​​的元素提取到一个列表中。此处的垂直斜线是匹配的模式 + WHERE 子句和用于填充列表元素的模式的表达式之间的分隔符。 (在这个查询中,我们只生成这个列表,所以我们可以得到它的大小)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    相关资源
    最近更新 更多