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

A new approach for deciding which union members to return! #362

Merged
merged 2 commits into from
Jul 28, 2021

Conversation

darrellwarde
Copy link
Contributor

Description

Excerpt from documentation which explains the change in detail:

Which union members are returned by a Query are dictated by the where filter applied.

For example, the following will return all user content, and you will specifically get the title of each blog.

query GetUsersWithBlogs {
    users {
        name
        content {
            ... on Blog {
                title
            }
        }
    }
}

Whilst the query below will only return blogs. We could for instance use a filter to check that the title is not null to essentially return all blogs:

query GetUsersWithAllContent {
    users {
        name
        content(where: { Blog: { title_NOT: null }}) {
            ... on Blog {
                title
            }
        }
    }
}

Conceptually, this maps to the WHERE clauses of the subquery unions in Cypher. Going back to the first example with no where argument, each subquery has a similar structure:

CALL {
    WITH this
    OPTIONAL MATCH (this)-[has_content:HAS_CONTENT]->(blog:Blog)
    RETURN { __resolveType: "Blog", title: blog.title }
UNION
    WITH this
    OPTIONAL MATCH (this)-[has_content:HAS_CONTENT]->(journal:Post)
    RETURN { __resolveType: "Post" }
}

Now if we were to leave both subqueries and add a WHERE clause for blogs, it would look like this:

CALL {
    WITH this
    OPTIONAL MATCH (this)-[has_content:HAS_CONTENT]->(blog:Blog)
    WHERE blog.title IS NOT NULL
    RETURN { __resolveType: "Blog", title: blog.title }
UNION
    WITH this
    OPTIONAL MATCH (this)-[has_content:HAS_CONTENT]->(journal:Post)
    RETURN { __resolveType: "Post" }
}

As you can see, the subqueries are now "unbalanced", which could result in massive overfetching of Post nodes.

So, when a where argument is passed in, we only include union members which are in the where object, so it is essentially acting as a logical OR gate, different from the rest of our where arguments:

CALL {
    WITH this
    OPTIONAL MATCH (this)-[has_content:HAS_CONTENT]->(blog:Blog)
    WHERE blog.title IS NOT NULL
    RETURN { __resolveType: "Blog", title: blog.title }
}

Issue

This is a new approach for the following PRs, which don't make so much sense for the new count queries and connection totalCount:

Checklist

The following requirements should have been met (depending on the changes in the branch):

  • Documentation has been updated
  • TCK tests have been updated
  • Integration tests have been updated
  • Example applications have been updated
  • New files have copyright header
  • CLA (https://neo4j.com/developer/cla/) has been signed

Copy link
Contributor

@danstarns danstarns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good, I just added two comments on the comments(meta).

@darrellwarde darrellwarde merged commit 5a81e33 into neo4j:2.0.0 Jul 28, 2021
@darrellwarde darrellwarde deleted the revert-union-changes branch May 9, 2022 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants