Filter vs Function performance

Is there any performance degradation from moving a filter to the @filter instead of the function?

Let’s say I have a type of Contact that has 30K nodes. I want to get all of them that have the Contact.firstName predicate equal to Anthony (8 Contacts). Here are two different ways to do that:

query {
  wType(func: type(Contact)) @filter(eq(Contact.firstName, "Anthony")) { uid }
  wOutType(func: eq(Contact.firstName, "Anthony")) { uid }
}

They will both provide the same results, but is either one better performance over the other?

As you may be aware, I am using the graphql endpoint but doing some advance filter logic through a DQL custom query. These filters will be built progmatically by user provided data in the UI. It is actually easier for me progmatically to use the example above wType way of doing it because then I can just insert the filter part wherever it may be needed and leave the type(Contact) code bit mostly the same. For instance I may be wanting to do a nested filter where I then need to add cascade and another nested bit of graph and then add the filter(s) onto that part. Here is a little more advance example that gets Contacts with (the firstName: Anthony and lastName: Master) or located in city Timbukto:

query {
  var1 as var(func: type(Contact)) @filter(eq(Contact.firstName, "Anthony"))
  var2 as var(func: type(Contact)) @filter(eq(Contact.lastName, "Master"))
  var3 as var(func: type(Contact)) @cascade {
    Contact.hasAddresses {
      HasAddress.address {
        Addr.city @filter(eq(City.name, "Timbuktu")) {
          City.name
        }
      }
    }
  }
  node(func: type(Contact)) @filter((uid(var1) AND uid(var2)) OR uid(var3)) {
    uid
  }
}
1 Like

Hi @amaster507, it is my understanding that, opening up a large root universe, like using func: type(Contact) on a large dataset of contacts, is less performant than putting a filter directly in there.

Ok, if that is the case, in the var3 example, would it be more efficient to use a has(Contact.hasAddresses) instead of the type function because that would only pull in ~2/3 of all Contacts hence making the universe smaller

Yes, has() would narrow the universe when compared to type(). I also agree that the way you are organizing the variables makes it easier for the audience to understand and maintain code/queries.

1 Like

thanks! All these filters will be generated by a lambda function with any number of different variables. The function returns the uids to the UI which then uses them in one last filter back against the graphql endpoint to get the auth rules applied. It’s a bit of a workaround for poor mans ACL, but I think it is a good solution. I might do a write up with the completed script sometime in the not too distant future if anyone else wants this added functionality

1 Like