0

set up events collection with 1 million records. Set up ChildEvents edge collection successfully.

   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

Total records : 999999 in ChildEvents Now I need to display all the parents/or children for the given node. In this case i am expecting the below query to return all the nodes from 350 to 99999. ( 350 --> 351 --> 352 --> ....999999 ) FOR v IN OUTBOUND "events/350" any ChildEvents RETURN v But this query returns only 2 records. If we use 1..200 it limits the no.of records returned. How to get n. number of records in this case?

For the same set up if we do using neo4J it returns all the nodes and i am expecting same behavior here.

Your help is greatly appreciated.

  • I don't quite understand the example. It looks like you're creating edges, but the query in your text: `FOR v IN OUTBOUND "events/350" any ChildEvents RETURN v` is not valid AQL. Also, I don't quite understand the child/parent relationship - how does "mynum + 1" figure in? – kerry Jan 25 '20 at 00:30
  • "ChildEvents" is the edge collection with mynum to get some automated no inserted. eg. {"source": "ABC", "target": "DEF", "tranno": "A12345", "type": "REST", "attributes": {"myPrd": "1"},"mynum": 1}. with this edge collection hierarchy has been established like 1-->2-->3-->4-->5...999999. How to display all the children nodes for the given node? For eg. if we provide node 4, the above query returns only 2 records 4, and 5, not the rest of the records. Expecting all the child nodes to be returned for the given node. – Solai Srinivasan Jan 25 '20 at 15:42

1 Answers1

0

So the child nodes will have the lowest values for mynum, and the parents will have the higher values, correct? For a test set, I created an events table like this:

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

And after creating a persistent hash index on mynum, I created the edges like this:

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

This generates a "from child to parent" graph like:

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

Then, you start at a node (say mynum == 50) and get all OUTBOUND edges (see anonymous graph docs) from hop x to hop y. I'm limiting these values (zero to one-hundred) to keep the number of returned documents low, but you can use any value.

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

Which returns 101 documents, starting at mynum: 50, like:

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

Setting the x to 0 returns the starting node, but changing it to 1 excludes it, starting to return nodes one hop away:

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

With this in mind, we can return nodes from any point in the graph. For instance, setting x to 99...

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

...would return only two nodes:

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

You can also define the "hop count" values via variables:

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

It doesn't look like you can drive them from a table (the DB can't build a plan), but you CAN create bind parameter(s) and pass the values that way:

/* 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();

Using bind parameters is language-dependent, but here are some links to get you started:

kerry
  • 757
  • 6
  • 16
  • Thanks Kerry. But my point is we are hard-wiring the numbers in for loop. Eg. FOR v IN 0..100 OUTBOUND event : In this snippet can we have record count dynamically populated from the table instead of giving 100 ? Sorry if my question was not clear initially. – Solai Srinivasan Jan 28 '20 at 03:26