子ノードに複数の親がある場合、Neo4J / Cypherを使用した大量の冗長パス分析を回避するにはどうすればよいですか?

aliteralmind

これにより、「id1」からちょうど2世代離れたすべての一意の親が返されます。

MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF*2..2]->(parent:LevelTwo)
    RETURN DISTINCT parent ORDER BY parent.id

これは、各子に親が1つしかない場合に正常に機能します。しかし、私のデータでは、ノードは複数の親を持つことができます(循環関係はありません)。による

PROFILE MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF*2..2]->(parent:LevelTwo)
    RETURN DISTINCT parent ORDER BY parent.id

数千のノードしかないため、これにより数千万のパスの組み合わせが発生し、リソースが不足するために一貫した障害が発生します。

たとえば、これを考えると

関係

「id1」がノードAであり、そのすべての親を3世代離したい場合は、子ごとに2回Dノードを「通過」します:ABDF、ACDF。

この冗長性を回避する方法は、次のように、一度に1世代ずつクエリを実行することです。

MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF]->(parent:LevelTwo)
    RETURN DISTINCT parent ORDER BY parent.id

(「* 2..2」の範囲はなくなりました)

返された親を収集し、それらを反復処理してIDを収集し、それらを使用して次世代の親にクエリを実行します。

MATCH (:LevelOne {id: "id1"})-[:ISCHILDOF]->(parent:LevelTwo)
    WHERE child.id IN [
        'id1001',
        'id1002',
        'id1003',
        'id1004',
        'id1005',
        'id1006',
        'id1013',
        'id1014',
        'id1015',
        'id1016',
        'id1017']
    RETURN DISTINCT parent
    ORDER BY parent.id

必要に応じて、いくつもの世代レベルでこれを繰り返します。

これを達成するためのより良い、より標準的な方法はありますか?

サイバーサム

[更新しました]

最古の世代の祖先

このアプローチは、検索対象の最も古い世代の祖先のみが必要な場合に役立ちます。世代を超えてクエリを生成するのは簡単です。

id「id1」であるノードから4世代離れた祖先を検索するとします

MATCH (:LevelOne { id: "id1" })-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH DISTINCT parent AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
RETURN DISTINCT parent AS ancestor;

多くのMATCH句は、世代数に対応しています。

このコンソールは、このアプローチを5世代にわたって示しています。

すべての世代の祖先(最も古い世代へのパス上にない場合でも)

このアプローチは、すべての世代の祖先を検索する場合に役立ちます。以下の例は4世代用です。

注:このアプローチでは、最古の世代への道を進んでいない人も含め、各世代のすべての祖先が一覧表示さます。

MATCH (:LevelOne { id: "id1" })-[:ISCHILDOF]->(parent:LevelTwo)
WITH COLLECT(DISTINCT parent) AS ancestors
WITH [ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
WITH generations+[ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
WITH generations+[ancestors] AS generations, ancestors UNWIND ancestors AS ancestor
MATCH (ancestor)-[:ISCHILDOF]->(parent:LevelTwo)
WITH generations, COLLECT(DISTINCT parent) AS ancestors
RETURN generations+[ancestors] AS generations;

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ