2016-04-18 11 views
1

2つのタイプのエッジで互いに接続されているノードの直後と直後を考えてみましょう。直接縁 の間とすることができるエッジが交差するエッジ Neo4j:適時に複数の関係と一致

  • 交差

    • 0..N直接縁
    • 0..1:クエリはすべて、以下の規則を満足する2つのノード間のすべての可能な経路を発見する必要があります

    これらのパスは、ノードAとnodeZの間で有効と見なされます。

    • (nodeA)-[:direct]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)(nodeA)-[:direct]->(nodeB)->[:direct]->(nodeC)-[:intersect]->(nodeZ)

  • (nodeA)-[:direct]->(nodeB)-[:intersect]->(nodeC)->[:direct]->(nodeZ)
  • (nodeA)-[:intersect]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)
  • は、基本的にはどこにでもパスではなく、一度だけ発生する可能性がエッジと交差します。 非既存のNeo4jのバージョンで私の理想的なCYPHERクエリは、この次のようになります。

    MATCH (from)-[:direct*0..N|:intersect*0..1]->(to)

    しかし:(エッジタイプのために複数の制約をのNeo4jサポートしていません

    UPDATE 23.04.16

    6609個のノード(合計550kのうち)、5184個の直接のタイプ(合計440kのうち)と34119のタイプの交差(37289個のうちの合計)です(いくつかの循環参照が予想されます(neo4jは回避しますか? ?)

    有望に見えたが、秒の形で終えることができなかったクエリ:

    MATCH p = (from {from: 1})-[:direct|intersect*0..]->(to {to: 99}) WHERE 123 < from.departureTS < 123 + 86400 //next day AND REDUCE(s = 0, x IN RELATIONSHIPS(p) | CASE TYPE(x) WHEN 'intersect' THEN s + 1 ELSE s END) <= 1 return p;

    答えて

    1

    これは、あなたがやりたいことになります。

    // Cybersam's correction: 
    MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)‌​) return DISTINCT p; 
    return p 
    

    ここで私が使用したテストシナリオがあります:

    create (a:nodeA {name: "A"}) 
    create (b:nodeB {name: "B"}) 
    create (c:nodeC {name: "C"}) 
    create (z:nodeZ {name: "Z"}) 
    
    merge (a)-[:direct  {name: "D11"}]->(b)-[:direct  {name: "D21"}]->(c)-[:direct  {name: "D31"}]->(z) 
    merge (a)-[:intersect {name: "I12"}]->(b)-[:direct  {name: "D22"}]->(c)-[:direct  {name: "D32"}]->(z) 
    merge (a)-[:direct  {name: "D13"}]->(b)-[:intersect {name: "I23"}]->(c)-[:direct  {name: "D33"}]->(z) 
    merge (a)-[:direct  {name: "D14"}]->(b)-[:direct  {name: "D24"}]->(c)-[:intersect {name: "I34"}]->(z) 
    merge (a)-[:intersect {name: "I15"}]->(z) 
    
    // Cybersam's correction: 
    MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)‌​) return DISTINCT p; 
    return p 
    

    私は間違いを犯しました。ブラウザ上のグラフは、 "p"で返されました - そうではありませんでした。すべての詳細を取得するには、レポートの「行」部分を調べる必要があります。

    このクエリは、要件に適合する単一のノードも返します。ここ

    +0

    あなたのお問い合わせが記載された要件に準拠していません。少なくとも1つの 'direct'で始まり、1つの' intersect'に続いて、最後に少なくとも1つの 'direct'が続くパスを返します。しかし、正しく動作するように変更することもできます(しかし、私の答えと同じくらいパフォーマンスは良くないかもしれません):MATCH p =((from) - [:direct * 0 ..] - >(middle) - [:intersect * 0。 (0)] - >(to))戻り値DISTINCT p; ' – cybersam

    +0

    これには、グラフに交差するエッジが存在するという唯一の要件があります。交差エッジもオプションの場合、[:intersect]は[:intersect *]に置き換えることができます。 –

    +0

    'intersect'は必須ではなく[0..1]、' direct' [0..N]でもありません。パスは「直接」で始まり、終わらなければならないという要件はありません。 – cybersam

    2

    は記載要件に準拠したクエリである:

    MATCH p = (from)-[:direct|intersect*0..]->(to) 
    WHERE REDUCE(s = 0, x IN RELATIONSHIPS(p) | 
        CASE WHEN TYPE(x) = 'intersect' THEN s + 1 ELSE s END) <= 1 
    return p; 
    

    それは0以上direct関係および0または1 intersect関係を持つすべてのパスを返します。

    +0

    私はそれを試みましたが、それは決して終わったことはありません(私は少なくとも30分以上走っていました)。いくつかの洞察で更新された質問を確認してください – mente

    +0

    私は元の質問 – mente

    +0

    にしようとしたクエリを追加した多分循環参考のために悪いですか? – mente

    関連する問題