Get unique values of a type attribute and count them WITH FILTERING

What I want to do

This topic has a query from:
Get unique values for a predicate?
I don’t know if I should have made this a reply on that post or if this warrants its own topic.

I’m trying to create an e-commerce page with filter checkboxes that are generated from the data. Each checkbox has a name and a count of how many parts would be available if you were to click that checkbox, like this:

Brands
▢ Some Brand (54)
▢ Another Brand (23)
▢ GenericBrand (75)

Rise
▢ 20 (21)
▢ 30 (82)
▢ 40 (36)
▢ 55 (13)

And so on.

The properties “length”, “rise”, “clampDiameter”, “steererDiameter”, “color”, “material” and “brand” on type stems are the ones that will have filters.

	type Stems  {
		id: ID!
		link: String!
		image: String!
		name: String!
		length: Int
		rise: Int
		clampDiameter: Float
		steererDiameter: String
		color: String
		material: String!
		price: Float!
		weight: Int
		brand: String!
	}

What I did

{
	distinctBrands(func: type(Stems)) @groupby(Stems.brand)  {
	count(uid) 
	}
}

This returns (truncated)

[
  {
    "@groupby": [
      {
        "Stems.brand": "Thomson",
        "count": 1
      },
      {
        "Stems.brand": "Easton",
        "count": 2
      },
      {
        "Stems.brand": "FSA",
        "count": 2
      }
    ]
  }
]

But when I set filters to simulate the user selecting filters in other categories:

{
	distinctBrands(func: type(Stems)) @groupby(Stems.brand) @filter(le(Stems.length, 40) AND ge(Stems.weight, 150) ) {
	count(uid) 
	}
}

I don’t get back the groups with a count of zero, which would make it easier to update the filter counts. I thought of assigning the unique brands to a variable, and then querying for the count and the name using the variable, but I’m not sure how to do that. I’d rather not have client side logic to find update the ones with a count of zero, which would work by comparing the unfiltered unique brands to the filtered ones and setting the count on the ones that are not present in the filtered query to zero.

I tried this:

{
	A as distinctBrands(func: type(Stems)) @groupby(Stems.brand)  {

	}
	q(func: uid(A)) {
        Stems.brand
		count(Stems.brand)
	}
}

But I get the error:

{
  "errors": [
    {
      "message": ": Query couldn't be executed",
      "extensions": {
        "code": "ErrorInvalidRequest"
      }
    }
  ],
  "data": null
}

I don’t know where to look or what to do to find out why this query isn’t working. Is there a Dgraph syntax highlighter? I looked at Query Variables in another query block I | Blocksvars | Dgraph Tour.
I’m posting this because I feel that this is a very common use case and also it would take me a very long time to figure out what’s wrong and someone here might be able to look at this and instantly know what to do. Should I not have posted and simply try harder with the Dgraph Tour?

Dgraph metadata

dgraph version

v21.03.0-78-ge4ad0b113

Yeah, that error message is not too helpful. There’s a syntax error in your query with A as distinctBrands.

I’m not picking up exactly what you’re laying down, but maybe a query like this might get you going in the right direction:

{
 	ITEMS as var(func: gt(Stem.weight, 39))
  
	q(func: uid(ITEMS)) @groupby(Stem.brand) {
		  count(uid)
	} 
}

@matthewmcneely Ohhh!! Var is a keyword! It has special meaning! Is there a list of other keywords somewhere?

Well this way returns the names and the count, as before, but unfortunately still does not return anything if the count is zero.

{
 	ITEMS as var(func: type(Stems)) @filter(le(Stems.length, 99))
  
	q(func: uid(ITEMS)) @groupby(Stems.brand) {
		  count(uid)
	} 
}


returns (truncated):

[
  {
    "Stems.brand": "Syntace",
    "count": 1
  },
  {
    "Stems.brand": "Thomson",
    "count": 1
  },
  {
    "Stems.brand": "TruVativ",
    "count": 1
  },
  {
    "Stems.brand": "FSA",
    "count": 2
  }
]

I found a way to do what I wanted, it’s sort of clumsy but it works!

First get the unique brands:

{
	distinctBrands(func: type(Stems)) @groupby(Stems.brand) 
}

returns:

    "distinctBrands": [
      {
        "@groupby": [
          {
            "Stems.brand": "Thomson"
          },
          {
            "Stems.brand": "Easton"
          },
          {
            "Stems.brand": "FSA"
          },
          {
            "Stems.brand": "Syntace"
          }
        ]
      }
   ]
}

Then get the count with the filter for each brand

	Thomson(func: eq(Stems.brand, "Thomson")) @filter(le(Stems.length, 99)) {
		count(uid)
	}

	Easton(func: eq(Stems.brand, "Easton")) @filter(le(Stems.length, 99)) {
		count(uid)
	}

	FSA(func: eq(Stems.brand, "FSA")) @filter(le(Stems.length, 99)) {
		count(uid)
	}
}

returns:

{
    "Thomson": [
      {
        "count": 1
      }
    ],
    "Easton": [
      {
        "count": 0
      }
    ],
    "FSA": [
      {
        "count": 2
      }
    ]
}