First:n returns not all the items

Hi!

I don’t quite get the issue here - i am trying to get first 10 items, but i get only like 5

Could you please help me out to understand what is the problem here? I am using the standard ML-100K data set

Hi @kostjaigin,

Welcome to the Dgraph and thanks for posting your query. You are getting only five results because of the @cascade directive in the ‘another’ query. With the @cascade directive, nodes that doesn’t have all predicates specified in the query are removed.

In this case, the first 10 results are selected and then the cascade removes the node which doesn’t have all the predicates.

To elaborate, if you run the following query (Note that there is no @cascade):

{
  tagret_genres(func: uid(0x30d72)){
    name
    genre{
      name
     }
  }
  
  film(func: uid(0x30d72)) {
    name
    uid
    count(rated)
    count(genre)
    g as genre
  }
  
  another(func:has(genre), first: 10, orderasc:name)  @normalize 
  {
  	Name:name
  	uid
  	genre @filter(uid(g)){
    	genreName: name
    }
  }
}

You’ll notice that the target genres i.e. the genres with which the movie “Star Wars (1977)” (uid: 0x30d72) is associated are the following:

          {
            "name": "Action"
          },
          {
            "name": "Adventure"
          },
          {
            "name": "Romance"
          },
          {
            "name": "Sci-Fi"
          },
          {
            "name": "War"

The section ‘another’ of the query filters the traversals to the genre based on if the genre’s uid is same as one of that of “Star Wars”. So for the first 10 nodes, the genre whose uid is same as one of that of Star Wars will be traversed while other genres will not be traversed. Thus, some of the nodes will have genres and some will not. This is evident by the result as “101 Dalmatians (1996)” doesn’t have any genre now:

"another": [
      {
        "Name": "'Til There Was You (1997)",
        "genreName": "Romance",
        "uid": "0x31254"
      },
      {
        "Name": "1-900 (1994)",
        "genreName": "Romance",
        "uid": "0x31289"
      },
      {
        "Name": "101 Dalmatians (1996)",
        "uid": "0x30e21"
      },
     ...

So, when we add @cascade directive, all those nodes are removed from the result of “another” which doesn’t contain genre predicate because of filtering.

Hope this answers your query. Feel free to ask follow-up questions.

2 Likes

Hi!

Thank you for the explanation! Now i am interested in getting the first 10 films that DO share a genre with “Star Wars” (e.g) → what would be the correct way to do so then?

Hey @kostjaigin,

You can do this by using the query variable, you store the uids of all the nodes whose genre matches with any of that of “Star wars” and then select the first 10 out of them.

{
  film(func: uid(0x30d72)) {
    name
    uid
    count(rated)
    count(genre)
    g as genre
  }
  
  u as var(func:has(genre)) @cascade
  {
  	genre @filter(uid(g)){
      genreName: name
    }
  }
  
  another(func: uid(u), orderasc:name, first:10){
    Name:name
  	uid
    genre {
      name
    }
  }
}

Hope it answers your query. Feel free to ask followup questions.