Tracking zero counts

Hello,

When using the count index at the query root, I regularly need to get values lower than a threshold, including zero.

For instance, suppose I have products connected to suppliers and I’d like to known when there are not enough suppliers. I could use the following query:

{
  me(func:lt(count(supplier), 3)) {
    uid
    product_name
  }
}

But I will miss the products with 0 suppliers: the most important ones to me.

I could use a second query block with a filter not has(supplier) but it is no efficient as not using any index.

What about adding an option on @count index to also track 0 counts?
It could be tracked only for the types containing the predicates with those indexes.

For example :

type Product {
  supplier
}
supplier: [uid] @count(zero) .

As you can see we don’t support/track negative counts (nonsensical) or zero counts (not tracked).

{
   q(func: eq(count(friend), 0)) {
       count(uid)
       name
    }
}

Result

Error Name: t

Message: : count(predicate) cannot be used to search for negative counts (nonsensical) or zero counts (not tracked).

URL: http://localhost:8080/query?timeout=60s&debug=true

Raw Error:

${
  "name": "t",
  "url": "http://localhost:8080/query?timeout=60s&debug=true",
  "errors": [
    {
      "message": ": count(predicate) cannot be used to search for negative counts (nonsensical) or zero counts (not tracked).",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ]
}

Other way

You can have a Type and then filter it by count. It works.

{
   q(func: type(Person)) @filter(eq(count(friend), 0)) {
       count(uid)
       name
    }
}
{
   q(func: has(name)) @filter(eq(count(friend), 0)) {
       count(uid)
       name
    }
}

Sample dataset

{
  "set":[
    {
      "name":"Alica","age":"13",
     "friend":[{"name":"bob","age":"12","dgraph.type":"Person"}],
      "dgraph.type":"Person"
    },
    {
      "name":"Lucas","age":"16",
      "dgraph.type":"Person"
    }
  ]
}

Thank you for your answer.

In terms of performances, does it mean that dgraph will first retrieve all persons and then intersect with those without friends?
Is it really efficient?

Yes

I don’t think so.

You can try to cheat this. Create a “fake” entity (as in my example, “a fake friend”) and then you will have all your nodes with at least 1 value. Hence you disregard this value and treat it as “Zero”. And in every query you have, you use “math” func to subtract that extra entity.

I see.
Then it would be a very useful and effective feature to track 0 counts.

So, fill up an issue. xD

Ok, done :slight_smile:

@MichelDiz @LGalatin

Hey guys, does similar filter functionality exist on the GraphQL endpoint yet? I need to retrieve all values that have no connections on a specific predicate.

Thanks :slight_smile:

1 Like

Neither has nor count are yet in the GraphQL queries.

Is it not has(pred) that fits your use case?

Yep! The graphQL version thereof is exactly what I need.

1 Like

Done. Top of the list for next sprint :slight_smile:

At first glance it looks a fairly simple port into GraphQL, so unless there’s a problem in there, it should be able to go into the 20.07.0

3 Likes

Woot, awesome! Thanks once again :slight_smile:

2 Likes

has(pred) for GraphQL is WIP, and will not be able to make into 20.07.0

Just a note: I think this should be follow up at [GitHub] Tracking zero counts

PS: Ohhh, there are two parallel topics… @minhaj what exactly is going to 20.07.0? Zero counts or has func?

Has func. I have edited my reply above. Thanks for pointing out.

1 Like

This is the PR for adding equivalent of has to GraphQL: feat(GraphQL): add has filter support by minhaj-shakeel · Pull Request #6258 · dgraph-io/dgraph · GitHub