Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for ability to traverse from optional nodes #7803

Closed
mwhitehead opened this issue Oct 9, 2017 · 3 comments
Closed

Request for ability to traverse from optional nodes #7803

mwhitehead opened this issue Oct 9, 2017 · 3 comments
Assignees

Comments

@mwhitehead
Copy link

OrientDB Version: 2.2.29+

OS: linux

Expected behavior

@luigidellaquila There is an existing issue requesting this, but it's been combined with another request that is effectively closed. I know it's on your todo list, but this feature is quite important for my team so thought it warranted its own issue.
For consistency's sake, I will re-post that request and example here:

Given this query:

MATCH {
    class: Foo,
    as: foo
}.out('Foo_Bar') {
    optional: true,
    as: optional_bar
}, {
    class: Bar,
    as: optional_bar
    **nullWhenEmpty: true** // additional keyword to conditionally trigger the behavior is acceptable
}.in('Baz_Bar') {
    as: baz
} RETURN $matches
If no matching Bar exists in the step that has optional: true, then it's just as
if the subsequent traversal didn't exist (because it starts at an optional 
location that doesn't exist) and $matched.baz should subsequently 
be null for the same reason.

Actual behavior

Not supported

Steps to reproduce

Please refer to details issue #6788

CC @obi1kenobi @smolinari @saeedtabrizi @santo-it

@obi1kenobi
Copy link
Contributor

I'm not tied to using that specific structure or that specific keyword to implement this -- I'd be happy with any solution that allows MATCH queries to traverse from an optional vertex. But yes, this would be amazing to have in the 2.2.x series!

@luigidellaquila
Copy link
Member

Hi @mwhitehead

Thank you for opening this specific issue, it will let us better track this feature.

My short term advice here is to try to re-write the query as follows:

SELECT foo, optional_bar, baz FROM (
   MATCH {
       class: Foo,
       as: foo
   }.out('Foo_Bar') {
       optional: true,
       as: optional_bar
   } RETURN foo, optional_bar, optional_bar.in("Baz_Bar") as baz
) UNWIND baz

I hope it helps

Thanks

Luigi

@obi1kenobi
Copy link
Contributor

Hey all, just wanted to give you a heads-up that the GraphQL compiler project has built a workaround for this issue:
pull request: kensho-technologies/graphql-compiler#83
documentation: https://github.com/kensho-technologies/graphql-compiler#expanding-optional-vertex-fields

The idea is that we can take a query that requires optional traversals, and represent it as the union of two queries: one where the traversal isn't optional but required, and one where the edge for that traversal is not allowed to exist.

The final compiled result looks something like the following:

SELECT EXPAND($final_match)
LET
    $match1 = (
        SELECT
            Animal___1.name AS `name`
        FROM (
            MATCH {
                class: Animal,
                as: Animal___1,
                where: (
                    (in_Animal_ParentOf IS null)
                    OR
                    (in_Animal_ParentOf.size() = 0)
                ),
            }
        )
    ),
    $match2 = (
        SELECT
            Animal___1.name AS `name`,
            Animal__in_Animal_ParentOf___1.name AS `parent_name`
        FROM (
            MATCH {
                class: Animal,
                as: Animal___1
            }.in('Animal_ParentOf') {
                as: Animal__in_Animal_ParentOf___1
            }.in('Animal_ParentOf') {
                as: Animal__in_Animal_ParentOf__in_Animal_ParentOf___1
            }
        )
    ),
    $final_match = UNIONALL($match1, $match2)

This corresponds to the following GraphQL query:

{
    Animal {
        name @output(out_name: "name")
        in_Animal_ParentOf @optional {
            name @output(out_name: "parent_name")
            in_Animal_ParentOf {
                name @output(out_name: "grandparent_name")
            }
        }
    }
}

This workaround will help until OrientDB is able to support such an operation natively, which I am sure would dramatically improve the performance of such queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants