简体   繁体   中英

arangodb nodes connected to multiple others

I'm just getting started with arangodb and have gotten to my first real problem:

Is it possible to search for nodes connected to all of multiple others? This seems like a basic operation for a graph db but I just can't think of a solution.

For reference, if we take the 'knows' example graph I want to know which persons know Charlie AND Dave (which should be only Bob)

knows example graph (not allowed to embed images yet)

For now my best guess is to start a traversal for all of the "targets" and reduce and filter the response myself, is this really the only way?

EDIT: OK, to further specify I have added another connection, eve knows dave too, but should NOT be returned since she does not know charlie

EDIT2: So far I've come up with this query

FOR start IN ['persons/charlie', 'persons/dave']
LET knownBy = (FOR v,e,p IN 1 INBOUND start knows
    RETURN v)
FOR p IN knownBy
    COLLECT person = p
    LET knows = (FOR v IN 1 OUTBOUND person._id knows
        RETURN v._id)
    FILTER knows ALL IN ['persons/charlie', 'persons/dave']
    RETURN person

However, this feels a bit unnatural, getting the persons known by 'X' to get the persons that know 'X'... Also, the profiler shows that about a third of the time is used for optimizing the plan, there has to be a better solution, right?

If we take the knows example and only search for two connected vertices you can start a traversal on one target with a depth of 2 and filter that the third vertex on the path has to be the second target, then you can just return the second vertex on the path.

FOR v, e, p IN 2 ANY 'persons/charlie' knows
  FILTER p.vertices[2]._id == 'persons/dave'
  RETURN p.vertices[1]

If you search for more than two vertices, the following query should work well. It starts a traversal with a depth of 1 and collect every _id of the person neighbors and checks of your targets are all containing in the neighbors.

LET targets = ['persons/charlie','persons/dave']

FOR person IN persons
  FILTER targets ALL IN FLATTEN((
    FOR v, e, p IN 1 ANY person._id knows
    RETURN v._id
  ))
  RETURN person

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM