How to Filter in graphql query correctly?

I have a new question.

So with the following Schema, I want to query for Profile that belongs to a user, given that I would know the user’s ID on the UI.

type User {
  id: String! @id @search(by: [hash])
  userName: String! @search(by: [hash])
  profile: Profile @hasInverse(field: user)
  posts: [Post!] @hasInverse(field: user)
}

type Profile {
  id: ID!
  user: User!
  coverPictureURL: String
  avatarPictureURL: String
  fullName: String @search
  city: String @search
}

type Post {
  id: ID!
  user: User!
  title: String! @search(by: [fulltext]) # TODO: remove title
  description: String
  createdAt: DateTime
  updatedAt: DateTime
}

So, I wrote my query like this:

query QueryUserProfile ($userId: String) {
  queryProfile  {
    user(filter: { id: { eq: $userId } })  {
      id
    }
    id
    fullName
    avatarPictureURL
    coverPictureURL
    city
  }
}

but this doesn’t work if I more than one users in the DB.
I get the following error:

{
      "message": "Non-nullable field 'user' (type User!) was not present in result from Dgraph.  GraphQL error propagation triggered.",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "queryProfile",
        1,
        "user"
      ]
    }

What am I doing wrong ?
Should I need to query User instead? with the filter applied ?

Ok so after reading some more, I got it working with following:


query QueryUserProfile($userId: String) {
  queryProfile @cascade(fields: ["user"]) {
    user(filter: { id: { eq: $userId } }) {
      id
    }
    id
    fullName
    avatarPictureURL
    coverPictureURL
    city
  }
}

Is it the correct way to do it ?

I will not say it is the wrong way, but it may not be the most efficient way. Consider if your graph had millions of profiles. Your query would traverse a million profiles to a million users and then filter those users to just the one you wanted and then remove all profiles except the one and return the response.

The better way to query a graph is start with the smallest known group of nodes, or single node, first.

query QueryUserProfile($userId: String!){
  getUser(id:$userId) {
    id
    profile {
      id
      fullName
      avatarPictureURL
      coverPictureURL
      city
    }
  }
}
1 Like

Thanks for the explanation. I was not confident about it anyway.

I have changed it to the way you have written it.