查找仅包含唯一路径的所有循环路径

eri*_*lee 3 neo4j cypher

我有以下代码来启动数据库

create
(C1: Company{name:'Company A'}),  
(C2: Company{name:'Company B'}), 
(C3: Company{name:'Company C'}),
(C4: Company{name:'Company D'}),
(C1)-[:Sell{contract:"TA1801"}]->(C2),
(C2)-[:Sell{contract:"TA1802"}]->(C3),
(C3)-[:Sell{contract:"TA1803"}]->(C1),
(C3)-[:Sell{contract:"TA1804"}]->(C4),
(C1)-[:Sell{contract:"TA1805"}]->(C4),
(C4)-[:Sell{contract:"TA1806"}]->(C1)
Run Code Online (Sandbox Code Playgroud)

假设我只想找到"A公司"的独特路径

MATCH path = (start:Company{name:"Company A"})-[r:Sell*]->(end:Company{name:"Company A"})
RETURN  path
Run Code Online (Sandbox Code Playgroud)

它返回五条路径

????????????????????????????????????????????????????????????????????????
?"path"                                                                ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1805"},{"name":"Company D"},{"nam?
?e":"Company D"},{"contract":"TA1806"},{"name":"Company A"}]           ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1805"},{"name":"Company D"},{"nam?
?e":"Company D"},{"contract":"TA1806"},{"name":"Company A"},{"name":"Co?
?mpany A"},{"contract":"TA1801"},{"name":"Company B"},{"name":"Company ?
?B"},{"contract":"TA1802"},{"name":"Company C"},{"name":"Company C"},{"?
?contract":"TA1803"},{"name":"Company A"}]                             ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1801"},{"name":"Company B"},{"nam?
?e":"Company B"},{"contract":"TA1802"},{"name":"Company C"},{"name":"Co?
?mpany C"},{"contract":"TA1803"},{"name":"Company A"}]                 ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1801"},{"name":"Company B"},{"nam?
?e":"Company B"},{"contract":"TA1802"},{"name":"Company C"},{"name":"Co?
?mpany C"},{"contract":"TA1803"},{"name":"Company A"},{"name":"Company ?
?A"},{"contract":"TA1805"},{"name":"Company D"},{"name":"Company D"},{"?
?contract":"TA1806"},{"name":"Company A"}]                             ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1801"},{"name":"Company B"},{"nam?
?e":"Company B"},{"contract":"TA1802"},{"name":"Company C"},{"name":"Co?
?mpany C"},{"contract":"TA1804"},{"name":"Company D"},{"name":"Company ?
?D"},{"contract":"TA1806"},{"name":"Company A"}]                       ?
????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

但是你可以看到与TA1806,TA1801,TA1802合约的关系卖出不止一次.一个具体的例子是TA1806出现在路线1,2,4和5中.TA1801出现在路线2,3,4,5中

我希望路径只包含与最短路径的唯一关系(最初我想要最长,但似乎复杂性增加了很多)

????????????????????????????????????????????????????????????????????????
?"path"                                                                ?
????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1805"},{"name":"Company D"},{"nam?
?e":"Company D"},{"contract":"TA1806"},{"name":"Company A"}]           ?
?????????????????????????????????????????????????????????????????????????
?[{"name":"Company A"},{"contract":"TA1801"},{"name":"Company B"},{"nam?
?e":"Company B"},{"contract":"TA1802"},{"name":"Company C"},{"name":"Co?
?mpany C"},{"contract":"TA1803"},{"name":"Company A"}]                 ?
????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

Inv*_*con 5

对于最长路径,您可以按长度订购路径并花费最长时间,但APOC有助于复制检查(除了起始节点,因为您需要电路):

MATCH path = (start:Company{name:"Company A"})-[r:Sell*]->(end:Company{name:"Company A"})
WHERE NOT apoc.coll.containsDuplicates(tail(nodes(path)))
WITH path
ORDER BY length(path) DESC
LIMIT 1
RETURN path
Run Code Online (Sandbox Code Playgroud)

不重复路径中节点的纯Cypher方法相当丑陋:

MATCH path = (start:Company{name:"Company A"})-[r:Sell*]->(end:Company{name:"Company A"})
    WHERE all(node in tail(nodes(path)) WHERE single(x in tail(nodes(path)) WHERE x = node))
    WITH path
    ORDER BY length(path) DESC
    LIMIT 1
    RETURN path
Run Code Online (Sandbox Code Playgroud)