Allow value variables in facet filters

Moved from GitHub dgraph/2406

Posted by djdoeslinux:

I would love to be able to interpolate value variables into @facet statements similarly to @filter statements. This would enable a new class of query dependent traversals for my use case and eliminate a lot of post-processing code in my application.

I will try to distill my current data model into a trivial, but relevant case tomorrow.

campoy commented :

Hi there, @djdoeslinux

What is exactly what you are requesting here? Do you mean having the facet name in a variable or the facet value that you want to compare the facet value with?

lucacanella commented :

I think I stumbled upon the same need.
I created a fictional case that should describe what I’m asking, please see details below:

Scenario
A classic person-rated-movie scenario, I want to find who gave the same rates to one or more movies I rated. Imagine following scenario:

(P1)-[Rated: 3].
                \
                 (Movie 1)-[Rated: 5]-(Me)
                /
(P2)-[Rated: 5]'

The matching pattern for my query should be: (P2)-[Rated: 5]->(Movie 1)<-[Rated: 5]-(Me)

Example
Please find example schema, data and queries in the attachment.
dgraph-facets-filter-variable.txt

What I tried to do
The query starts from node “(Me)”, then gets all rated movies with facets. Actual rates are an int facet for “rated” predicate, so for each movie I want to find all the people that rated that same movie given the value of the rate is the same that has been detected first. I tried to achieve it this way:

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

I obviously get this error:

Error Name: t
Message: line 9 column 24: variables are not allowed in facets filter.

I tried other ways, like treating ratings as nodes, but still could’nt get away with this.

Hardcoding a value, instead of using a variable with val, succedes:

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

MichelDiz commented :

It seems reasonable to me. Value variables could come from other blocks and amplify the possibilities of querying.

{
  q(func: anyofterms(name, "Alice Bob Charlie")) {
    value as math(5)
    rated @facets @facets(eq(rating, val(value))) {
      uid
    }
  }
}