Query all of a given category (with sub-categories)

I Want to Do

I have two types of Nodes, Categories and Products - and Categories can have related subcategories (which are themselves Categories).

I’m trying to query root Categories (categories without any parent category), each with a list of communities representing all the communities related to any subcategory of that root category.

Using @recurse gives me a nested result, (Category → Subcategory → [Communities]) - but I’m looking to return a flattened list (Category → [Communities])

Any help is appreciated!!

Recurse won’t work for that case. Try to use normalize

{
  q(func: type(Category)) @filter(NOT has(<~Subcategory>)) {
    Subcategory @normalize {
      Communities: Communities
    }
  }
}

What are(I mean the type) Communities? a string? objects? How many sub cats it can have?

Communities are nodes as well.

Normalize as above will return a category object with a normalized subcategory field. I’m looking to return a community field with a list of any community related to any subcategory - if that makes sense.

I’d like to traverse the graph until all subcategories (and subcategories of subcategories) are traversed.

How many sub cats it may have? Do you mind sharing the desired result? I think I know how to. But a mock of the desired result would be great.

How many sub cats it may have?

Unlimited

Desired result:

{
  "data": {
    "query": [
      {
        "uid": "0x9df7",
        "Category.name": "Example Category",
         "products": [
           {uid: "0xxdf7", product_name: "Example Product"},
           {uid: "0xfdf7", product_name: "Example Product #2"},
           ......
         ]
      }
    ]
  }
}

The products are under Communities?

Sorry, I meant to write Category - not Communities.

Categories have many products, and products can have many categories.

Thinking…

Can you share the recurse query you have tried?

The way I have thought would work for a single root category. So you would do a query for each category.

Actually, I think I was able to figure it out with your help :slight_smile:

{
  query(func: type(Category)) @filter(NOT has(Category.categories)) @recurse {
    uid
    name: Category.name
    products: Category.products
    product_name: Product.name
  }
}

The only thing is I had to add the parent categories to all child products to get this to work :confused: Do you know of a way where this isn’t needed?

Nice, I was about to recommend this

{
  query(func: type(Category)) @filter(NOT has(Category.categories)) @recurse {
    uid
    name: Category.name
    products: Category.products @normalize
    product_name: Product.name
  }
}

To check if it work.

Actually nevermind - that did work!

Not sure if I got.

This predi param (NOT has(Category.categories)) should not be reversed? - nvm too

Thanks for the help :pray:

1 Like

@MichelDiz Sorry, I was manually adding the Products to the parent Category - so it turns out that this:

{
  query(func: type(Category)) @filter(NOT has(Category.parent_categories)) @recurse {
    uid
    name: Category.name
    products: Category.products
    product_name: Product.name
  }
}

returns:

{
"data": {
    "query": [
      {
        "uid": "0x9e23",
        "name": "Category #1 (no subcategories)",
        "products": [
          {
            "uid": "0x9e24",
            "product_name": "Product #1"
          }
        ]
      },
      {
        "uid": "0x9e28",
        "name": "Category #2 (with subcategories))"
      }
    ]
  }
}

The problem is that Product #2 is related the a subcategory of Category #2, which are being filtered out by @filter(NOT has(Category.parent_categories))

So, still stuck :rofl:

@MichelDiz I think what I need is

_foreach
1 Like

Weird. So why this appears in the response? it should be filtered out. The category itself should be excluded if it has Category.parent_categories predicate.

The params at the query root are applied only in the root objects. The nested ones follows the rules in the query body.

Category #2 has no parents - so it appears.

Category #3 is a subcategory of Category #2, so it doesn’t appear.

Product #2 is listed under Category #3, so it’s not returned either.