Search code examples
orientdbtraversalgraph-databasesgremlin

OrientDB traverse (children) while connected to a vertex and get an other vertex


I'm not sure the title is the best way to phrase it, here's the structure:

Structure

Here's the db json backup if you want to import it to test it: http://pastebin.com/iw2d3uuy

I'd like to get the Dishes eaten by the Humans living in Continent 1 until a _Parent Human moved to Continent 2. Which means the target is Dish 1 & 2.

If a parent moved to another Continent, I don't want their dish nor the dishes of their children, even if they move back to Continent 1. I don't know if it matters, but a Human can have multiple children.

If there wasn't the condition about the children of a Human who has moved from the Continent, this query would have worked:

SELECT expand(in('_Is_in').in('_Lives').in('_Eaten_by'))
FROM Continent WHERE continent_id = 1

But I guess here we're forced to use (among other things)

TRAVERSE out('_Parent') FROM Human WHILE

I've tried to use the while of traverse with a subquery to get all the Humans I'm interested in, before to try to get the Dishes, but I'm not even sure we can use while with a subquery.

I hope the structure will help other users to quickly find out if this query is useful to them. If anyone is wondering, I used the Graph tab of OrientDB Studio to make it, along with GIMP.

As a bonus, if anyone knows the Gremlin syntax, it would also be useful to learn it.

Please feel free to edit this post as you see fit and contribute your thoughts :)


Solution

  • SELECT expand(in('_Eaten_by'))
    FROM (TRAVERSE out('_Parent')
          FROM (SELECT from Human WHERE in('_Parent').size() = 0)
          WHILE out('_Lives').out('_Is_in').continent_id = 1)
    

    Explanation:

    • TRAVERSE out('_Parent') FROM (SELECT FROM Human WHERE in('_Parent').size() = 0) WHILE out('_Lives').out('_Is_in').continent_id = 1

    returns Human 1 and 2.

    That query traverses Human, starting from Human 1 while the Human is connected to Continent 1.

    It starts from in('_Parent').size() = 0 which are the Humans without any _Parent (there's only Human 1 in this case) (size() is the size of the collection of vertices coming in from _Parent).

    • And SELECT expand(in('_Eaten_by')) FROM

    gets the Dishes, starting from the Humans we got from the traversal and going through the edge _Eaten_by.

    Note: be sure to always use ' around the vertices and edges names, otherwise the names don't seem to be taken in account.