Nodes ordering task

Hello.

I would like to talk about the ordering of the nodes in the graph.

There are two entities: category and product.
N categories can contain N products.
The same product can simultaneously belong to N categories.
Task: to be able to manage the order of products in a subset of products of each category.

Possible solutions.

First.

Each category has a category.products edge pointing to the products belonging to this category. Order determines by the facet (priority = 1,2,3,4 … etc.).

Schema:

category.name: string.
category.products: uid.

product.name: string.

Data:

_: c1 <category.name> "category1" .
_: c2 <category.name> "category2" .
_: c3 <category.name> "category3" .

_: p1 <product.name> "product1" .
_: p2 <product.name> "product2" .
_: p3 <product.name> "product3" .
_: p4 <product.name> "product4" .
_: p5 <product.name> "product5" .

_: c1 <category.products> _: p1 (priority=1) .
_: c1 <category.products> _: p2 (priority=2) .
_: c1 <category.products> _: p3 (priority=3) .
_: c1 <category.products> _: p4 (priority=4) .
_: c1 <category.products> _: p5 (priority=5) .

_: c2 <category.products> _: p1 (priority=1) .
_: c2 <category.products> _: p2 (priority=2) .
_: c2 <category.products> _: p4 (priority=3) .
_: c2 <category.products> _: p5 (priority=4) .

_: c3 <category.products> _: p2 (priority=1) .
_: c3 <category.products> _: p4 (priority=2) .
_: c3 <category.products> _: p5 (priority=3) .

Benefits:

  • simplicity of perception.

Disadvantages:

  • facets do not have indexes and are not suitable for sorting
  • if you change the order of the elements, you need to recalculate the priority (for example, if you move the last element to the top of the list, its priority should become 1, and all other priority + 1; maybe Dgraph has a built-in recalculation mechanism?)

Second.

Each category has a category.products edge pointing to the first product belonging to this category. Order determines by the edge product.next of each particular product. Each edge has a facet (<category.uid> = true) for the ability to get a “chain” of products of a particular category.

Schema:

category.name: string .
category.products: uid .

product.name: string .
product.next: uid .

Data:

_: c1 <category.name> "category1" .
_: c2 <category.name> "category2" .
_: c3 <category.name> "category3" .

_: p1 <product.name> "product1" .
_: p2 <product.name> "product2" .
_: p3 <product.name> "product3" .
_: p4 <product.name> "product4" .
_: p5 <product.name> "product5" .

_: c1 <category.products> _: p1 .
_: c2 <category.products> _: p1 .
_: c3 <category.products> _: p2 .

_: p1 <product.next> _: p2 (category1=true,category2=true) .
_: p2 <product.next> _: p3 (category1=true) .
_: p2 <product.next> _: p4 (category2=true,category3=true) .
_: p3 <product.next> _: p4 (category1=true) .
_: p4 <product.next> _: p5 (category1=true,category2=true,category3=true) .

Benefits:

  • the ability to change the order of products by breaking old ties and creating new ones

Disadvantages:

  • the need for multiple checks in the code when changing the order of products
    • whether there is a edge between products
      • if it does not exist, you must create it and specify the current category as a facet
      • if there is, then you must add a new facet without losing existing ones
  • N facets at each edge looks strange
  • even with a small number of categories and products, their connections begin to drive people crazy

Disadvantages of the second solution suggest an absurdity.

The task seems to be extremely burning, and for sure I’m not the first one to face it.

I would be grateful for any ideas and thoughts on this topic.

P.S.

Sorry for awful english.

The second solution is not a great one IMHO.

The first one is intuitive and simple but as you figured out sorting facets might be a bit slow. Though how many products does each category have? What kind of queries do you plan to do? Is it going to be to get all products in a category or across all categories?

Dgraph doesn’t have a built-in calculation mechanism for now. As a workaround, you could instead store priorities in reverse order. You can also maintain a counter for the highest priority for a category. So, when you want to update the priority of something you just give it a higher priority than what has been allocated before. Though this would only work if you want to increase the priority of a product to highest. Not sure if that’s what you want.

Another scalable method could be to have intermediate nodes.

_:c2 <category.products> _:cp1 .
_:cp1 <priority> "1" .
_:cp1 <product> _:p1 .

_:c2 <category.products> _:cp2 .
_:cp2 <priority> "2" .
_:cp2 <product> _:p2 .

This way you could still make use of the indexes while sorting.

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