【问题标题】:Filter neo4j result, return distinct combination of node IDs过滤 neo4j 结果,返回不同的节点 ID 组合
【发布时间】:2020-02-29 06:42:30
【问题描述】:

我有一个包含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)

我只想返回一组节点一次(无论它们之间存在多少不同的航班),但with 行不起作用。基本上我想要创建的是一种新类型的变量“对象”,它具有三个 ID 作为其属性并在其上运行不同。在neo4j中这可能吗?如果没有,有什么解决方法吗?

【问题讨论】:

  • 目前我正在考虑的是,由于所有 ID 都是 5 位长,我将 first.ID 乘以 10^10,second.ID 乘以 10^5 并将这些与未修改的 third.ID 相加,因为这会为每组节点创建一个唯一编号。但在我看来,这是一个非常丑陋的解决方法
  • 你能关闭这个问题的早期版本吗? stackoverflow.com/questions/58683952/….

标签: sql neo4j graph-databases


【解决方案1】:

您可以返回带有键或数组的对象。例如:

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

UNWIND range(1, 10000) AS i
WITH 
  [ toInteger(rand()*3), toInteger(rand()*3), 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])

【讨论】:

    【解决方案2】:

    您可以使用 APOC 函数 apoc.coll.sort 对 3 个 IDs 的每个列表进行排序,以便 DISTINCT 选项正确地将具有相同 IDs 的列表视为相同。

    这是一个使用 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]]))
    

    注意:second &lt;&gt; first 测试可能没有必要,因为不应有任何航班(如果“航班”与“腿”相同)从机场飞回自身。 em>

    【讨论】:

      猜你喜欢
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多