首页 > 解决方案 > 如何显示 arangoDB 中的所有子边缘节点 [nth level like neo4J]

问题描述

设置包含 100 万条记录的事件集合。成功设置 ChildEvents 边缘集合。

   FOR c IN events
        FOR p IN events  
            FILTER p.mynum == ( c.mynum + 1 )
                INSERT { _from: c._id, _to: p._id}  INTO ChildEvents
                    RETURN $NEW

总记录:ChildEvents 中的 999999 现在我需要显示给定节点的所有父/子。在这种情况下,我期望下面的查询返回从 350 到 99999 的所有节点。( 350 --> 351 --> 352 --> ....999999 ) FOR v IN OUTBOUND "events/350" any ChildEvents RETURN v 但是这个查询只返回 2 条记录。如果我们使用 1..200 它会限制返回的记录数。如何获得 n。这种情况下的记录数?

对于相同的设置,如果我们使用 neo4J,它会返回所有节点,我希望这里有相同的行为。

非常感谢您的帮助。

标签: arangodb

解决方案


所以子节点将具有最低的值mynum,而父节点将具有更高的值,对吗?对于一个测试集,我创建了一个events这样的表:

FOR n IN 1..99999
    LET doc = { mynum: n }
    INSERT doc INTO events

在 上创建持久哈希索引mynum,我创建了这样的边缘:

FOR c IN events
    FOR p IN events
        FILTER p.mynum == ( c.mynum + 1 )
        LET edge = { _from: c._id, _to: p._id }
        INSERT edge INTO ChildEvents

这会生成一个“从子到父”图,例如:

    parent  <---  child  [ <---  child(n) ... ]

然后,您从一个节点(比如)开始,从 hop到 hopmynum == 50获取所有OUTBOUND边(参见匿名图文档)。我限制这些值(零到一百)以保持返回文档的数量较少,但您可以使用任何值。xy

FOR event in events
    FILTER event.mynum == 50
    FOR v IN 0..100 OUTBOUND event
        ChildEvents
        RETURN v

它返回 101 个文档,从 开始mynum: 50,例如:

[
  {
    "_id": "events/285436",
    "mynum": 50
  },
  {
    "_id": "events/285437",
    "mynum": 51
  },
  {
    "_id": "events/285438",
    "mynum": 52
  },
  ...
]

设置x0返回起始节点,但将其更改为1排除它,开始返回节点一跳:

[
  {
    "_id": "events/285436",
    "mynum": 51
  },
  {
    "_id": "events/285437",
    "mynum": 52
  },
  {
    "_id": "events/285438",
    "mynum": 53
  },
  ...
]

考虑到这一点,我们可以从图中的任何点返回节点。例如,设置x为 99...

FOR event in events
    FILTER event.mynum == 50
    FOR v IN 99..100 OUTBOUND event
        ChildEvents
        RETURN v

...只会返回两个节点:

[
  {
    "_id": "events/285535",
    "mynum": 149
  },
  {
    "_id": "events/285536",
    "mynum": 150
  }
]

您还可以通过变量定义“跳数”值:

LET n_start = 100
LET n_end = 999
FOR event in events
    FILTER event.mynum == 50
    FOR v IN n_start..n_end OUTBOUND event
        ChildEvents
        RETURN v

看起来您不能从表中驱动它们(数据库无法构建计划),但您可以创建绑定参数并以这种方式传递值:

/* JavaScript */
const aql = [
    'FOR event in events',
    '    FILTER event.mynum == 50',
    '    FOR v IN @n_start..@n_end OUTBOUND event',
    '        ChildEvents',
    '        RETURN v',
];
const vars = {
    n_start: 100,
    n_end: 999,
};
const result = await db._query(aql.join('\n'), vars).toArray();

使用绑定参数取决于语言,但这里有一些链接可以帮助您入门:


推荐阅读