Question

I have hierarchical data (categories) stored in a mySql database using the nested set model.

All is working perfectly only I now need the ability to add a property to any node (force_to_top) which will set the node to temporarily force to the top of its siblings, and I'm not 100% sure how to do this without physically changing the lft and rgt values.

When a nodes force_to_top property is turned on I don't want to store the original lft and rgt values elsewhere, change the lft and rgt values to move the node to the correct position, and then reset their original lft and rgt values once the force_to_top property is removed. I think that's going to cause massive problems further down the line, plus it seems like a very roundabout way of doing things? (correct me if that's in fact the simplest way! But I would like to find another, preferably only using sql not updating any values in the db)

I was wondering if it would be possible to somehow manipulate the output of the sql depending on the force_to_top property?

For example if we have the following structure

        Cars
        |
-----------------
|       |       |
Audi    Ford    VW

Which would have the following lft/rgt/force_to_top values:

node    lft    rgt  force_to_top
Cars    1      8    false
Audi    2      3    false
Ford    4      5    false
VW      6      7    false

When we output the child nodes of 'Cars', we'd be given:

Audi
Ford
VW

But lets say the node 'VW' has its force_to_top property set to true, what I would really need is the output of the child nodes of 'Cars' to now be:

VW
Audi
Ford

As I mentioned I've thought about storing the original lft and rgt values and resetting them after the force_to_top property is removed. The plus side of not doing it this way is the speed of turning off the force_to_top property, it would mean no data manipulation other than actually setting the force_to_top value to false again and the node would immediately drop back to its original position. And would also mean I don't need to create a storage area / extra tables / extra fields for the original lft and rgt values of each node.

I've also thought about doing this in the php after I've fetched the results, but for large data sets that could really slow things down.

I originally had to set the force_to_top nodes to the top of everything, which was very easy, simply ORDER BY force_to_top, lft, however now only forcing to the top of its siblings is a lot more complicated, as the node may be in the centre of a massive hierarchy.

Any suggestions or a point in the right direction would be much appreciated.

Was it helpful?

Solution

Just in case anyone stumbles here with a similar problem (very unlikely!):

In the end the only way I could find to achieve this functionality was to store the category's current parent_id and nearest_sibling_id when its force_to_top value was set to true.

This way I could move the category to the top of its parent by updating its lft and rgt values, and then when the force_to_top was removed, I could check the nearest_sibling_id still existed, and that it was still within the original parent_id. If so, move the category back next to its nearest_sibling_id; if not, just move the category to the bottom of its original parent_id as we can't determine where it really was originally positioned as our nearest_sibling_id value is out of date.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top