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.

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

Update(2021): just fixed the query.

{
var(func: eq(userlist.publicId, "1010")){
userlist.userInterests @facets (priority){
id as skills.skillPublicId
}
}
{
my(func: eq(userlist.publicId, "1010")){
username: userlist.username
publicId: userlist.publicId
collaboration: userlist.collaboration @facets(skillPublicId: skillPublicId) @facets(eq(skillPublicId, val(id))){
username: userlist.username
publicId: userlist.publicId
}
}
}
}

I’m trying to find the userInterests for a given user and these userInterests in a variable named id are used to filter the facets. But I’m getting this error (please find the attached screenshots) This works if I hardcode a value.

Please help me, thanks!