Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Filter nodes based on related aggregations #110

Closed
matthiasak opened this issue Feb 21, 2017 · 15 comments
Closed

Filter nodes based on related aggregations #110

matthiasak opened this issue Feb 21, 2017 · 15 comments

Comments

@matthiasak
Copy link

I'd like to add a few more pragmas for filtering. Currently we can filter a direct entity for certain in, contains, startsWith, etc filters, like:

{
  allGroups(filter: {
    members_every: { verified: true }
  }){
    name
  }
}

But, we can't make a query on allGroups filtering by metadata or aggregates. One idea is to enable special filters that test sub-entities such as the below example query where I would like to filter for groups who have atleast 1 member

{
  allGroups(filter: {
    count_gte: [0, {members: {verified: true}}]
  }){
    name
  }
}
@marktani marktani changed the title Filter entities based on state of related sub-entities Filter nodes based on related aggregations Feb 21, 2017
@marktani
Copy link
Contributor

marktani commented Mar 2, 2017

Related to #70.

@kabriel
Copy link

kabriel commented Mar 15, 2017

I need to be able to query for all objects (lets say Cars) that do not have an owner (User) relation set. I'm not sure of the best syntax:

{
  allCars(
    filter: {
      owner_none
    }
  ) {
    id
  }
}

@marktani
Copy link
Contributor

marktani commented Mar 16, 2017

I think for to-one relations this syntax would work best:

{
  allCars(
    filter: {
      owner: null
    }
  ) {
    id
  }
}

and for to-many:

{
  allOwners(
    filter: {
      cars: []
    }
  ) {
    id
  }
}

@marktani
Copy link
Contributor

marktani commented Apr 24, 2017

@kabriel, it's now possible to query nodes that are not related in a to-one relation:

{
  noOwner: allCars(
    filter: {
      owner: null
    }
  ) {
    id
  }
  someOwner: allCars(
    filter: {
      owner_not: null
    }
  ) {
    id
  }
}

@matthiasak
Copy link
Author

@marktani @kabriel this feature seems incomplete.

Graphcool console is giving errors on the following:

selection_027
selection_028
selection_029

null works, but I can't check for not_null or exists...

@matthiasak
Copy link
Author

workaround is slightly varied checks based on nesting level and ways to check...

persons: allPersons(
            filter:{
                verified: false
                ${valid ? `, avatar: {id_not:null}, name_not: "", bio_not: null, bio_not: "", user: {id_not:null}` : ''}
                ${invalid ? `, OR: [{avatar: {id: null}}, {name: ""}, {bio: null}, {user: {id: null}}]` : ''}
            }
            , first: ${pageSize}
            , skip: ${pageSize * page}
            , orderBy: ${orderBy}
        )

@marktani
Copy link
Contributor

@matthiasak the syntax is avatar: null and avatar_not: null. Did you try that?

@matthiasak
Copy link
Author

matthiasak commented Apr 25, 2017 via email

@marktani
Copy link
Contributor

Please create a issue report here: https://github.com/graphcool/api-bugs/issues 🙂

@marktani
Copy link
Contributor

Thanks to @mewdriller for this workaround to query nodes that are not connected in a to-many relation:

{
  allOwners(
    filter: {
      cars_every: {
        id: "-1"
      }
    }
  ) {
    id
  }
}

@adrianocola
Copy link

The following syntax seems to be working now for filtering nodes that are not connected in a to-many relation:

{
  allOwners(
    filter: {
      cars_every: {
        id: null
      }
    }
  ) {
    id
  }
}

And to do the opposite (filter nodes that have connections in a to-many relation), this is working:

{
  allOwners(
    filter: {
      cars_some: {
        id_not: null
      }
    }
  ) {
    id
  }
}

cars_some: { id_not: "-1" } works too.

This is the right way to do it, comparing id to null?

@sorenbs
Copy link
Member

sorenbs commented Nov 14, 2017

Thank you for this great suggestion!

Please have a look in the spec proposal to see if all your needs are met:-) https://github.com/graphcool/framework/issues/1279

@sorenbs sorenbs closed this as completed Nov 14, 2017
@samuela
Copy link

samuela commented Oct 25, 2018

I came across this problem today as well. I have a data model that looks something like:

type User {
  id: ID! @unique
  createdAt: DateTime!
  updatedAt: DateTime!

  emailAndPassAuth: EmailAndPasswordAuth @relation(name: "UserEmailAndPassAuth", onDelete: CASCADE)
  # githubAuth: GithubAuth
  # etc...
}

type EmailAndPasswordAuth {
  id: ID! @unique
  email: String! @unique
  passwordHashed: String!
  user: User! @relation(name: "UserEmailAndPassAuth")
}

Now, I get a new login attempt with an email and a password. I can find the corresponding EmailAndPasswordAuth node without any trouble, but getting the ID of the corresponding User is a real pain. In SQL it wouldn't be an issue since it's right there in the joint table, but now I'm stuck with two different queries: one to find the EmailAndPasswordAuth and then check that it matches, and yet another to then find the User node matching it.

@sorenbs
Copy link
Member

sorenbs commented Oct 25, 2018

@samuela - I might be missing something obvious, so please let me know if I am :-)

Can you not do a single query like this?

query {
  EmailAndPasswordAuths(where: email: $email, passwordHashed: $password) {
    user {
      id
    }
  }
}

@samuela
Copy link

samuela commented Oct 25, 2018

@sorenbs Ah, so it is a little bit trickier than that because the salt is also contained in passwordHashed! So what I really need to is something like

  • fetch the EmailAndPasswordAuths record for the given email,
  • bcrypt.compare(password, passwordHashed) or something like that,
  • if things check out, get the User id for that EmailAndPasswordAuths record. In SQL this would just be a foreign key in that table or whatever. But AFAIU prisma client doesn't offer a way to do this without a second db query: db.emailAndPasswordAuth({ id: nodeId }).user().

I came across this issue after a bit of googling about the problem, but on further inspection it looks like this may not be immediately relevant to the issue in this thread, so I'd be happy to move this elsewhere if you think that makes sense.

@schickling schickling reopened this Dec 6, 2018
@janpio janpio closed this as completed Sep 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants