gpt4 book ai didi

tree - 如何在 Neo4j 中映射树结构?

转载 作者:行者123 更新时间:2023-12-04 12:54:46 24 4
gpt4 key购买 nike

我正在描述 Neo4j 中的树结构数据集。在我当前的模型中,一个节点可以有 n 个到其他节点的链接,使其成为这些节点的子节点:

root
|
\-- A
|
\-- 1
|
\-- 2
  • 根链接
  • 1 和 2 链接到 A
  • root 是 A
  • 的父级
  • 1 和 2 是 A
  • 的 child

    因为我使用的是 nodejs(使用 node-neo4j),所以数据库的读取仅限于使用 Cypher。要读取节点,我使用以下查询:
    START n=node(1)
    -- this is the root node

    MATCH (n)<-[linkedby:links*]-x, x-[linksto?:links*1]->()
    -- get all nodes that link to the root node and all nodes linking to those nodes, etc, etc and retrieve all nodes those found nodes link to

    RETURN n, x, linkedby, LAST(linkedby) AS parent, COLLECT(DISTINCT linksto) AS links
    -- the last in the path of linkedby is the direct parent

    ORDER BY length(linkedby), parent.rank?
    -- ordering so that parents are fetched before their children from the result set

    我的问题:随着节点和关系数量的增加,此查询变得非常慢(> 1 秒)。

    有没有更好的方法来建模节点和关系?父节点和子节点之间是否需要不同的关系?或者我应该以任何方式更改查询?

    感谢您的任何指点!

    1)现实世界的问题:
    一种业务流程工具,其中服务与流程、组织、团队等相关联,以提供信息何时需要哪些服务以及由谁提供,并提供谁将提供此服务或负责的信息。

    所以例如:

    服务 S 用于进程 P1 和 P2:
    P1  P2
    | |
    \---+-- S

    服务 S 由团队 T 管理:
    T
    |
    \-- S

    T 队是 O 组织的一部分:
    O
    |
    \-- T

    树:
    root
    |
    |
    +-- Processes
    | |
    | +-- P1
    | | |
    | | \-- S
    | |
    | \-- P2
    | | |
    | | \-- S
    |
    +-- Organisations
    | |
    | +-- O
    | |
    | \-- T
    | |
    | \-- S

    2) 我在 console.neo4j.org 中的数据:
    CREATE 
    (r {name:'root'}),
    (ps {name: 'Processes'})-[:links]->r,
    (p1 {name: 'P1'})-[:links]->ps,
    (p2 {name: 'P2'})-[:links]->ps,
    (s {name: 'Service'})-[:links]->p1,
    s-[:links]->p2,
    (org {name: 'Organisations' })-[:links]->r,
    (t {name: 'Team'})-[:links]->org,
    s-[:links]->t

    最佳答案

    所以,我和Michael Hunger聊了聊前几天,他承认 Cypher 不擅长(还)处理递归查询。这应该在 2.1 中改变,但在那之前他建议我写一个 unmanaged extension ,然后我可以从 nodejs 调用它。

    这完全解决了我的问题:使用普通 Java 检索树比使用 Cypher 快 10 倍左右。

    简化代码:

    public class EntitiesStream {
    public Entity load(long nodeId) {
    Node n = database.getNodeById(nodeId);
    Entity entity = Entity.from(n);
    loadChildren(n, entity);
    return entity;
    }

    private void loadChildren(Node n, Entity e) {
    for (Relationship linksFrom: n.getRelationships(Direction.INCOMING, Relationships.links)) {
    Node startNode = linksFrom.getStartNode();
    Entity childEntity = Entity.from(startNode);
    e.addChild(((Number) linksFrom.getProperty("rank")).longValue, childEntity);
    this.loadChildren(startNode, childEntity);
    }
    }
    }

    public class Entity {
    private final TreeMap<Long, Entity> sortedChildren;

    Entity(long dbId) {
    this.sortedChildren = new TreeMap<>();
    // ...
    }

    public static Entity from(Node node) {
    Entity e = new Entity(node.getId());
    // ...

    return e;
    }

    public void addChild(Long rank, Entity childEntity) {
    sortedChildren.put(rank, childEntity);
    }
    }

    关于tree - 如何在 Neo4j 中映射树结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18868865/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com