Howto filter by propagating a variable

In a simple movielens-like scenario I want to get all the people that gave the same ratings to some of the movies I rated.

I first tried to achieve this by using facets but, since I cannot use variables in facets filters, I ended up adding a comment to an issue on github about this (Allow value variables in facet filters · Issue #2406 · dgraph-io/dgraph · GitHub). Since I’m a beginner with DGraph I wanted to know if there is another way to get this by using facets instead of the one I described in the issue.

In the meanwhile I tried another way using a “Rating” node to join people to movies. This isn’t working either, most probably because I’m not getting it right with variables and filters.
Can someone help me with this please? Here is the sample schema, data and query:

################
# Schema

<name>: string @index(exact, term) @upsert .
<rated>: [uid] @reverse .
<movie>: uid @reverse .
<rate>: int .

type Person {
  name
  rated
}

type Rating {
  movie
  rate
}

type Movie {
  name
}


#################
# Data

{
  set {
    
    #Movies
    _:t <dgraph.type> "Movie" .
    _:t <name> "Movie 1" .
    
    #People
    _:a <dgraph.type> "Person" .
    _:a <name> "Me" .
    
    _:b <dgraph.type> "Person" .
    _:b <name> "P1" .
    
    _:c <dgraph.type> "Person" .
    _:c <name> "P2" .
    
    #Ratings
    _:a1 <dgraph.type> "Rating" .
    _:a1 <movie> _:t .
    _:a1 <rate> "5" .
    _:a <rated> _:a1 .
    
    _:b2 <dgraph.type> "Rating" .
    _:b2 <movie> _:t .
    _:b2 <rate> "3" .
    _:b <rated> _:b2 .
    
    _:c3 <dgraph.type> "Rating" .
    _:c3 <movie> _:t .
    _:c3 <rate> "5" .
    _:c <rated> _:c3 .
  }
}
#################
# Load scenario

{
  scenario(func: type("Person")) @filter(eq(name,"Me")) @ignorereflex {
    name
    rated {
      rate
      movie {
        name
        ~movie {
          rate 
          ~rated {
            name
          }
        }
      }
    }
  }
}

#First try: Get people who rated at least one movie as I did
### Fails with error: "Message: : eq expects atleast 1 argument."
{
  b(func: type("Person")) @filter(eq(name, "Me")) @ignorereflex @cascade {
    name
    rated {
      rate1 as rate
      movie {
        name
        with_ratings: ~movie @filter(eq(rate, val(rate1))) {
          rate
          people: ~rated {
            name
          }
        }
      }
    }
  }
}

#Second try: Get people who rated at least one movie as I did
### Fails: empty result set
{
  b(func: type("Person")) @filter(eq(name, "Me")) @ignorereflex @cascade {
    name
    rated {
      rate1 as rate
      movie {
        name
        with_ratings: ~movie @filter(eq(rate2, val(rate1))) {
          rate2: rate
          people: ~rated {
            name
          }
        }
      }
    }
  }
}

Okay, I have accepted it to back log.

1 Like

Thank you, and what about the other solution? The one not involving facets, I still don’t get why it fails. I also tried different solutions with different variables and aliases but can’t get it to work

This happens cuz each piece of the query is kind of independent. For me, it turns out to be a bug. Also, I have an internal discussion about this.

As you can see at https://docs.dgraph.io/design-concepts/#queries. During a query, Dgraph searches for each pred/edge. It would be at different groups and so on. So technically each pred is a “call”. And they are independent per se. So, when you use it in the same query block. It accuses that it is missing an argument. Cuz that predicate was empty (the query for it has not yet been made or for some reason, and the value has not been saved to be used in the nested block - AND the nested block won’t wait for the parent to finish).

A workaround for this issue is by doing two blocks. e.g.

{
   K as var(func: type("Person")) @filter(eq(name, "Me")) {
       rated {
        rate1 as rate
       }
   }
  b(func: uid(K) ) @ignorereflex @cascade {
    name
    rated {
      movie {
        name
        with_ratings: ~movie @filter(eq(rate, val(rate1))) {
          rate
          people: ~rated {
            name
          }
        }
      }
    }
  }
}
1 Like

I have opened the topic. Promise a nested block (under construction - I'm still working in the use case)

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.