Proper management of Multirelational types

I’m currently trying to create a proper relationship between Product, Category, and Subcategory types, but I’m struggling to keep it working as intended. My goal is to create a system where I can use an index to get all the Product refs by Category or by Subcategory. Currently I imagine that each Product document would then have a list of category names and a list of subcategory names which is connected to the actual Category and Subcategory documents (Categories and Subcategories would also keep a list of Product names, all for readability). Based on my understanding though, relations would lock this solution to Ref connections within a different helper Collection/Index, which is also alright, just harder to read what a product is connected to.

Now onto the current confusion with my implementation…
I read through the documentation on relations in FQL but I’m not sure I really understand it fully yet. Here is my graphql schema:

type Product {
  productName: String! @unique
  categories: [Category!] @relation(name: "product_category")
  subcategories: [Subcategory!] @relation(name: "product_subcategory")}

type Category {
  categoryName: String! @unique  <-- I'd add a relation here if it was possible
  subcategories: [Subcategory!] @relation
  products: [Product!] @relation(name: "product_category")
}

type Subcategory {
  subcategoryName: String! @unique <-- I'd add a relation here if it was possible
  category: Category! <-- Subcategory *might* be able to have multiple Categories
  products: [Product!] @relation(name: "product_subcategory")
}

Using this schema, I created a Category and linked a Subcategory to it using the create mutation (So now I have a separate helper collection called category_subcategory which manages this).

When I tried to make use of this new Category by connecting it to the product:

mutation {
  partialUpdateProduct(id: "myProductId", data: {
    categories: [
       {connect: "myCategoryId"}
    ]
  }) {
    _id
    categories {
      categoryName
      subcategories {
        data
        {subcategoryName}
      }
    }
  }
}

I run into this error:

Expected type ‘ID!’, found ‘{connect: "myCategoryId"}’. String or Int value expected

I honestly just want the Product’s category and subcategory to be connected to the category and subcategory for easier viewing, but all I really need to store is just the name. I feel like if I could get the products to have a list of category names and subcategory names, but have it be connected to existing categories/subcategories it would in turn be cleaner. I guess whatever works with the best scalability would be the route I’d want to take. I appreciate any comments or suggestions. Thanks!

As you noted, references are used to manage relationships, which are more efficient for fetching the related documents than additional indexes on an extra field such as categoryName.

Replace myCategoryId with a document reference ID and your query should work.

In order to use your name field, you would need to create a customer resolver. You could use this to establish connections for easier to read mutations, but materializing the results would still rely on the underlying reference ids.

type Mutation {
  connectCategoryToProduct(productName: String!, categoryName: String!): Product @resolver
}
mutation {
  connectCategoryToProduct(productName: "Thing1", categoryName: "Gizmos") {
    _id
    categories {
      categoryName
      subcategories {
        data
        {subcategoryName}
      }
    }
  }
}
1 Like

Thanks this is helpful, I think I’m going to alter it a bit to just have Category and Product where Category has multiple levels and keeps track of each child Category, that way I can add subcategories with time and have it query for Products by each Category. I’ll have to make some functions to help manage d3coupling/removing these categories. Hopefully it goes well

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.