Unfortunately, the DB engine does not let you treat edges as nodes.  I 
suspect it breaks the math used for traversal and shortest path negotiation.

However, there might be several ways to solve this problem, although it's 
hard to say for sure without knowing more about your data model.  I did a 
few tests, and although it might not be possible to solve with a single 
traversal, there are options.

My data set includes two collections, appropriately named "nodes" and 
"edges", and a named graph called "nodegraph" that includes these.  Since 
edges are documents just like nodes but with two special attributes 
("_from" and "_to"), I added a "cause" attribute to each edge:
{
"*nodes*": [
{ "*_id*": "nodes/a" },
{ "*_id*": "nodes/b" },
{ "*_id*": "nodes/c" },
{ "*_id*": "nodes/d" }
],
"*edges*": [
{ "*_from*": "nodes/a", "*_to*": "nodes/b", "*cause*": "x" },
{ "*_from*": "nodes/d", "*_to*": "nodes/b", "*cause*": "NOT x" }
]
}

One option would be to find an OUTBOUND path from A, then look up other 
INCOMING paths from the end vertex ("nodes/b" in this case), filtering-out 
nodes that also have a conflicting cause ("NOT x" in this example).

FOR v,e IN 1 OUTBOUND 'nodes/a'
    GRAPH 'nodegraph'
    LET myCause = [ e.cause ]
    LET otherCauses = UNIQUE(
        FOR vv,ee IN 1 INBOUND v
            GRAPH 'nodegraph'
            RETURN ee.cause
    )
    FILTER 'NOT x' not in OUTERSECTION(myCause, otherCauses)
    RETURN v


You could also filter out nodes that have multiple causes:

FOR v,e IN 1 OUTBOUND 'nodes/a'
    GRAPH 'nodegraph'
    LET myCause = [ e.cause ]
    LET otherCauses = UNIQUE(
        FOR vv,ee IN 1 INBOUND v
            GRAPH 'nodegraph'
            RETURN ee.cause
    )
    FILTER LENGTH(
        OUTERSECTION(myCause, otherCauses)
    ) == 0
    RETURN v


If this doesn't quite fit, you could insert another "causes" collection in 
the middle of the edge.  So, instead of a single hop from A to B:

   *A  **--edge { cause }-->*  *B*

it would become two hops, with a "cause" node between:

   *A  **--edge-->*  *cause  **--edge-->*  *B*


The real trick depends on how you determine that a given node has multiple 
causes.  The examples here are one way, but maybe you could do it with 
SHORTEST_PATH and using weights, or even calculating the total weight for a 
given path (cause "x" has weight "5" whereas cause "NOT x" has an opposite 
value of "-5").



On Saturday, February 1, 2020 at 1:05:35 PM UTC-8, Jack Park wrote:
>
> That may sound like a strange question, but here's a somewhat trivial 
> example:
>
> Suppose this triple
> { A, cause, B  }
> And suppose this triple
> { D, cause, B  }
>
> Suppose it is determined that the first triple contradicts the second one.
> One approach is to (somehow) reify each triple as Vertex objects, then 
> link them with a "contradicts" Edge.
>
> But, what if, in some architecture, it is agreed that the Edge itself, 
> since it references both of its vertices, and has its own "type", in fact, 
> stands as if it is a Vertex representing the entire triple. In that 
> context, you simply wire an Edge between the two Edges.
>
> N'est-ce pas?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"ArangoDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/arangodb/16055983-5dd8-4dcf-bac8-35341bafb867%40googlegroups.com.

Reply via email to