Graph 在Neo4j中查询路径,如何只显示一次节点/边缘信息?
如果对两个节点之间的路径进行简单查询Graph 在Neo4j中查询路径,如何只显示一次节点/边缘信息?,graph,neo4j,Graph,Neo4j,如果对两个节点之间的路径进行简单查询 MATCH (m{name:'m'}), (n{name:'n'}), path = (m)-[:SOME_EDGE*]->(n) RETURN path EDIT: (example result) ... segments: [ { start: { id: 1 labels: [lbl1, lbl2, ...], properties: [p1, p2, ...] } end: {
MATCH (m{name:'m'}), (n{name:'n'}),
path = (m)-[:SOME_EDGE*]->(n)
RETURN path
EDIT:
(example result)
...
segments: [
{
start: {
id: 1
labels: [lbl1, lbl2, ...],
properties: [p1, p2, ...]
}
end: { ... }
properties: { ... }
},
{
start: {
id: 1
labels: [lbl1, lbl2, ...] <--- duplicate
properties: [p1, p2, ...] <--- duplicate
}
},
...
]
但是如何向上述结果中添加节点/关系信息(一个实体只需添加一次)
有没有办法在一次查询中完成此操作?您需要将路径、节点和关系收集到一个不同的列表中,然后使用以下函数基于它们生成一个映射:
MATCH path = (A)-[*]->(B)
UNWIND nodes(path) AS n
UNWIND relationships(path) AS r
WITH
collect(DISTINCT path) as paths,
collect(DISTINCT n) AS nodes,
collect(DISTINCT r) AS rels
RETURN
[p IN paths | {
nodes: [n IN nodes(p) | id(n)],
rels: [r IN relationships(p) | id(r)]
}] as paths,
reduce(acc={}, n IN nodes | apoc.map.setKey(acc, toString(id(n)), n)) as nodes,
reduce(acc={}, r IN rels | apoc.map.setKey(acc, toString(id(r)), r)) as rels
您需要将路径、节点和关系收集到一个不同的列表中,然后使用以下函数基于它们制作映射:
MATCH path = (A)-[*]->(B)
UNWIND nodes(path) AS n
UNWIND relationships(path) AS r
WITH
collect(DISTINCT path) as paths,
collect(DISTINCT n) AS nodes,
collect(DISTINCT r) AS rels
RETURN
[p IN paths | {
nodes: [n IN nodes(p) | id(n)],
rels: [r IN relationships(p) | id(r)]
}] as paths,
reduce(acc={}, n IN nodes | apoc.map.setKey(acc, toString(id(n)), n)) as nodes,
reduce(acc={}, r IN rels | apoc.map.setKey(acc, toString(id(r)), r)) as rels
stdob——在放松和收集方面是正确的,实际上不需要使用APOC
几个月前我自己提出了一个解决方案,今天来到这里,所以我选择了他/她的答案,并在这里发布了我的解决方案,没有APOC
放松和重新收集是关键
MATCH p=(m{name:'m'})-[:'SOME_EDGE'|:'SOME_OTHER_EDGE'*1..2]->(n{name:'n'})
WITH {
pathNodes: [node IN nodes(p) | ID(node)],
rels: [r IN RELATIONSHIPS(p) | {id:ID(r),ty:TYPE(r)}]
} AS path, p
UNWIND NODES(p) AS node
RETURN {paths:COLLECT(path), nodes: COLLECT(DISTINCT{id:ID(node),name:node.name})}
stdob——在放松和收集方面是正确的,实际上不需要使用APOC
几个月前我自己提出了一个解决方案,今天来到这里,所以我选择了他/她的答案,并在这里发布了我的解决方案,没有APOC
放松和重新收集是关键
MATCH p=(m{name:'m'})-[:'SOME_EDGE'|:'SOME_OTHER_EDGE'*1..2]->(n{name:'n'})
WITH {
pathNodes: [node IN nodes(p) | ID(node)],
rels: [r IN RELATIONSHIPS(p) | {id:ID(r),ty:TYPE(r)}]
} AS path, p
UNWIND NODES(p) AS node
RETURN {paths:COLLECT(path), nodes: COLLECT(DISTINCT{id:ID(node),name:node.name})}
你能举一个例子说明你在第一次查询中的重复项吗?因为在第二个查询中,结果是相同的,所以您只是更改了结果的投影……假设您只有两个节点,并且它们之间有三条边。每个边都有“开始”、“结束”和“关系(rel类型和rel的属性)。”这里的“开始”和“结束”是无意义重复的节点。那么您想要的结果格式是什么?节点路径的不同结果,因此在您的示例中,两个节点只有一个结果?在上面的第二个代码中,我只选择了id(节点),但我真正想要的是完整的节点信息(与第一个代码一样,但只有一次)与边放在一起。如果我选择不对节点使用投影,则整个节点信息将在路径上的每个外观上重复。您能否给出第一次查询中重复的示例?因为在第二个查询中,结果是相同的,所以您只是更改了结果的投影……假设您只有两个节点,并且它们之间有三条边。每个边都有“开始”、“结束”和“关系(rel类型和rel的属性)。”这里的“开始”和“结束”是无意义重复的节点。那么您想要的结果格式是什么?节点路径的不同结果,因此在您的示例中,两个节点只有一个结果?在上面的第二个代码中,我只选择了id(节点),但我真正想要的是完整的节点信息(与第一个代码一样,但只有一次)与边放在一起。如果我选择不为节点使用投影,则整个节点信息将在路径上的每个外观上重复。