Sql 过滤neo4j结果,返回节点ID的不同组合

Sql 过滤neo4j结果,返回节点ID的不同组合,sql,neo4j,graph-databases,Sql,Neo4j,Graph Databases,我有一个带有Airport节点和Flight关系的图,我想从一个特定的节点中找到三角形,其中边彼此的长度都在10%以内 MATCH path = (first:Airport{ID: 12953})-[f1:Flight]-> (second:Airport)-[f2:Flight]-> (third:Airport)-[f3:Flight]-> (last:Airport{ID: 12953}) W

我有一个带有
Airport
节点和
Flight
关系的图,我想从一个特定的节点中找到三角形,其中边彼此的长度都在10%以内

MATCH path = (first:Airport{ID: 12953})-[f1:Flight]->
             (second:Airport)-[f2:Flight]->
             (third:Airport)-[f3:Flight]->
             (last:Airport{ID: 12953})
WHERE second.ID <>first.ID AND 
      third.ID <>first.ID AND 
      f1.Distance<=(1.1*f2.Distance) AND 
      f1.Distance<=(1.1*f3.Distance) AND 
      f2.Distance<=(1.1*f1.Distance) AND 
      f2.Distance<=(1.1*f3.Distance) AND 
      f3.Distance<=(1.1*f1.Distance) AND 
      f3.Distance<=(1.1*f2.Distance)
WITH (first.ID, second.ID, third.ID) as triplet
return count(DISTINCT triplet)
匹配路径=(第一个:机场{ID:12953})-[f1:Flight]>
(第二:机场)-(f2:航班]->
(第三:机场)-(f3:航班]->
(最后:机场{ID:12953})
其中second.ID first.ID和
第三个ID第一个ID和

f1.距离可以返回带有键或数组的对象。例如:

UNWIND range(1, 10000) AS i
WITH 
  { 
    id1: toInteger(rand()*3), 
    id2: toInteger(rand()*3), 
    id3: toInteger(rand()*3) 
  } AS triplet
RETURN DISTINCT triplet

更新。可以通过重用查询中的变量、指定路径长度和使用列表函数来简化查询:

MATCH ps = (A:Airport {ID: 12953})-[:Flight*3]->(A)
WITH ps 
WHERE reduce(
  total = 0, 
  rel1 IN relationships(ps) | 
  total + reduce(
    acc = 0, 
    rel2 IN relationships(ps) | 
    acc + CASE WHEN rel1.Distance <= 1.1 * rel2.Distance THEN 0 ELSE 1 END
  )) = 0
RETURN count(DISTINCT [n IN nodes(ps) | n.ID][0..3])
MATCH ps=(A:Airport{ID:12953})-[:Flight*3]->(A)
带ps
何处减少(
总计=0,
关系中的rel1(ps)|
总计+减少(
acc=0,
关系中的rel2(ps)|

acc+CASE当rel1.Distance时,可以返回带有键或数组的对象。例如:

UNWIND range(1, 10000) AS i
WITH 
  { 
    id1: toInteger(rand()*3), 
    id2: toInteger(rand()*3), 
    id3: toInteger(rand()*3) 
  } AS triplet
RETURN DISTINCT triplet

更新。您可以通过重用查询中的变量、指定路径长度和使用列表函数来简化查询:

MATCH ps = (A:Airport {ID: 12953})-[:Flight*3]->(A)
WITH ps 
WHERE reduce(
  total = 0, 
  rel1 IN relationships(ps) | 
  total + reduce(
    acc = 0, 
    rel2 IN relationships(ps) | 
    acc + CASE WHEN rel1.Distance <= 1.1 * rel2.Distance THEN 0 ELSE 1 END
  )) = 0
RETURN count(DISTINCT [n IN nodes(ps) | n.ID][0..3])
MATCH ps=(A:Airport{ID:12953})-[:Flight*3]->(A)
带ps
何处减少(
总计=0,
关系中的rel1(ps)|
总计+减少(
acc=0,
关系中的rel2(ps)|

acc+案例当rel1.Distance时,您可以使用APOC函数对每个3个
ID
s列表进行排序,这样
DISTINCT
选项将正确地将具有相同
ID
s的列表视为相同

下面是一个使用APOC函数的简化查询:

MATCH path = (first:Airport{ID: 12953})-[f1:Flight]->
             (second:Airport)-[f2:Flight]->
             (third:Airport)-[f3:Flight]->
             (first)
WHERE second <> first <> third AND 
      f2.Distance<=(1.1*f1.Distance)>=f3.Distance AND
      f1.Distance<=(1.1*f2.Distance)>=f3.Distance AND 
      f1.Distance<=(1.1*f3.Distance)>=f2.Distance
RETURN COUNT(DISTINCT apoc.coll.sort([first.ID, second.ID, third.ID]]))
匹配路径=(第一个:机场{ID:12953})-[f1:Flight]>
(第二:机场)-(f2:航班]->
(第三:机场)-(f3:航班]->
(一)
第二个第一个第三个
f2.距离=f3.距离和
f1.距离=f3.距离和
f1.距离=f2.距离
返回计数(不同的apoc.coll.sort([first.ID,second.ID,third.ID]]))

注:
second-first
测试可能没有必要,因为不应该有任何飞行(如果“飞行”与“航段”相同)从机场飞回自身。

您可以使用APOC功能对每个包含3个
ID
s的列表进行排序,这样
DISTINCT
选项将正确地将具有相同
ID
s的列表视为相同

下面是一个使用APOC函数的简化查询:

MATCH path = (first:Airport{ID: 12953})-[f1:Flight]->
             (second:Airport)-[f2:Flight]->
             (third:Airport)-[f3:Flight]->
             (first)
WHERE second <> first <> third AND 
      f2.Distance<=(1.1*f1.Distance)>=f3.Distance AND
      f1.Distance<=(1.1*f2.Distance)>=f3.Distance AND 
      f1.Distance<=(1.1*f3.Distance)>=f2.Distance
RETURN COUNT(DISTINCT apoc.coll.sort([first.ID, second.ID, third.ID]]))
匹配路径=(第一个:机场{ID:12953})-[f1:Flight]>
(第二:机场)-(f2:航班]->
(第三:机场)-(f3:航班]->
(一)
第二个第一个第三个
f2.距离=f3.距离和
f1.距离=f3.距离和
f1.距离=f2.距离
返回计数(不同的apoc.coll.sort([first.ID,second.ID,third.ID]]))

注:
second-first
测试可能没有必要,因为不应该有任何飞行(如果“飞行”与“航段”相同)从机场飞回自己。

目前我想的是,由于所有ID都是5位数,我先将
第一个.ID
乘以10^10,
第二个.ID
乘以10^5,然后将它们与未修改的
第三个.ID
相加,因为这会为每一组节点创建一个唯一的数字。但这是一个非常糟糕的解决方法我的意见是你可以结束这个问题的早期版本吗?目前我想的是,由于所有ID都是5位数,所以我先将
第一个.ID
乘以10^10,
第二个.ID
乘以10^5,然后将它们与未修改的
第三个.ID
相加,因为这会为每组节点创建一个唯一的数字。但这确实是一个问题我认为这是一个丑陋的解决办法你能结束这个问题的早期版本吗。