propel nested set behavior - propel

I woudl like to build an oriented Graph using propel. The behavior I am looking for is similar to the nested set but with multiple parents for one child.
What exists:
P: Parent Node
C: Child Node
(0,1)P <- (0,n)C
What I need:
(0,n)P <- (0,n)C
I have read this:
http://propelorm.org/behaviors/nested-set.html
and that: https://github.com/CraftyShadow/EqualNestBehavior
Could you give me some direction please?

I found a solution, I am using a ManyToMany relationship with the same table on the two relations links.
table Node
Table ParentNode (ParentFK: Node, NodeFK: Node)

Related

Extract Xpath local-name of parent node of the grandchildren by knowing only the root node name

The problem lies on the fact that I am not able to extract a specific child node local-name when I only know the parent node name, example below:
I know that the parent node (root) is "companies" even for other tables i always know the first one. My question is how to know what is the local-name of the parent node that contains the grandchildren.
//companies//child::node()/text()* -> this returns the grandchildren
The answer should be industry. Would that be any generic logic that would also give me the same thing but for example the parent node local-name of the grand grand children , so a structure of 3 nested tables.
<companies>
<id>3</id>
<display_name>abc</display_name>
<fun_name>12345</fun_name>
<industry>
<name>System</name>
<level_1>45</level_1>
<level_2>4510</level_2>
<level_3>451030</level_3>
<level_4>45103020</level_4>
</industry>
<abc>xxxxx</abc>
</companies>
Thank you
Regards
JP
I think you want this
local-name(parent::*)
For the parent localname of grandchildren of companies:
local-name(//companies/*/*/..)
For great-grandchildren:
local-name(//companies/*/*/*/..)
and so on
An alternate way to express this would be:
local-name(//companies/*[*])
and for great-grandchildren
local-name(//companies/*[*/*])

how do I sort a collection with child property?

I should sort parent based on a field of child.
sample code;
IQueryable<Parent> data = context.Parents.Include(o=>o.Children);
//Child has a member (string) Name.
question: how can I sort Parent by Children Names.
Your question is somewhat confusing, since first of all, it is tagged both with Entity Framework and LINQ-to-SQL. Which ORM are your actually using?
Secondly, and more to the point, you say that you want to "sort Parent by Children Names". Which child name do you want to sort by? You do realize that you can't compare a list of names to another list of names and decide which one should come before the other?
So if I assume you want to sort by the child name that comes first lexicographically, your solution would be the following (#Paul was close on this one, but you need to specify the property you are sorting by):
context.
Parents.
OrderBy(p => p.
Children.
OrderBy(c => c.Name).Select(c => c.Name).FirstOrDefault()
);
In this case, consider the following setup. Parent PA has children CB and CD while parent PB has children CC and CA. As a result of the sorting, parent PB will come first in the sorted list, since child CA will be used as the "main" child for PB, while CB will be the "main" child for PA. If that's not the behavior you are looking for, please provide an example and a clearer description.
You can take one of the children names to sort by, probably select it by doing the corresponding sorting?
Something like:
IQueryable<Parent> data = context.Parents.OrderBy(
p=>p.Children.OrderBy(chi => chi.Name).FirstOrDefault());

What is the best way to add and order to Doctrine Nested Set Trees?

What is the best way to add a sense of order in Doctrine Nested Sets?
The documention contains several examples of how to get al the childeren of a specific node
$category->getNode()->getSiblings()
But how can I for example:
change the position of the fourth sibling to the second position
get only the second sibling
add a sibling between the second and third child
etc...
Do I have to manually add and ordercolumn to the model to do these operations?
To get the second previous sibling:
$anotherCategory = $category->getNode()->getPrevSibling()->getNode()->getPrevSibling();
To insert category in its place:
$category->getNode()->moveAsPrevSiblingOf($anotherCategory);
To add a new sibling between second and third child, you'd simply use insertAsNextSiblingOf instead of moveAsPrevSiblingOf.

How can I show a flat representation of a GtkTreeStore in a GtkTreeView?

I have a TreeStore with objects that I view and manipulate through a GtkTreeView/GtkTreeModel setup.
I also have a TreeView showing a TreeModelSort of the TreeStore, which I use for sorting on columns like name and date.
The problem is, that the sort mechanism only sorts the root nodes, even if a underlying child node has e.g. a date that is later/sooner than the roo tnodes' dates.
So, the question is if there is any way to show the objects as a List, not a tree, but keeping the references to the paths in the other TreeView?
I would suggest a TreeModelFilter that filters out any rows that are child rows (ie, depth > 1). You can filter your sorted model, and display just the root nodes.

How do I implement threaded comments?

I am developing a web application that can support threaded comments. I need the ability to rearrange the comments based on the number of votes received. (Identical to how threaded comments work in reddit)
I would love to hear the inputs from the SO community on how to do it.
How should I design the comments table?
Here is the structure I am using now:
Comment
id
parent_post
parent_comment
author
points
What changes should be done to this structure?
How should I get the details from this table to display them in the correct manner?
(Implementation in any language is welcome. I just want to know how to do it in the best possible manner)
What are the stuff I need to take care while implementing this feature so that there is less load on the CPU/Database?
Thanks in advance.
Storing trees in a database is a subject which has many different solutions. It depends on if you want to retrieve a subhierarchy as well (so all children of item X) or if you just want to grab the entire set of hierarchies and build the tree in an O(n) way in memory using a dictionary.
Your table has the advantage that you can fetch all comments on a post in 1 go, by filtering on the parentpost. As you've defined the comment's parent in the textbook/naive way, you have to build the tree in memory (see below). If you want to obtain the tree from the DB, you need a different way to store a tree:
See my description of a pre-calc based approach here:
http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=17746&ThreadID=3208
or by using balanced trees described by CELKO here:
or yet another approach:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
If you fetch everything in a hierarchy in memory and build the tree there, it can be more efficient due to the fact that the query is pretty simple: select .. from Comment where ParentPost = #id ORDER BY ParentComment ASC
After that query, you build the tree in memory with just 1 dictionary which keeps track of the tuple CommentID - Comment. You now walk through the resultset and build the tree on the fly: every comment you run into, you can lookup its parentcomment in the dictionary and then store the comment currently processed also in that dictionary.
Couple things to also consider...
1) When you say "sort like reddit" based on rank or date, do you mean the top-level or the whole thing?
2) When you delete a node, what happens to the branches? Do you re-parent them? In my implementation, I'm thinking that the editors will decide--either hide the node and display it as "comment hidden" along with the visible children, hide the comment and it's children, or nuke the whole tree. Re-parenting should be easy (just set the chidren's parent to the deleted's parent), but it anything involving the whole tree seems to be tricky to implement in the database.
I've been looking at the ltree module for PostgreSQL. It should make database operations involving parts of the tree a bit faster. It basically lets you set up a field in the table that looks like:
ltreetest=# select path from test where path <# 'Top.Science';
path
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
However, it doesn't ensure any kind of referential integrity on its own. In other words, you can have a records for "Top.Science.Astronomy" without having a record for "Top.Science" or "Top". But what it does let you do is stuff like:
-- hide the children of Top.Science
UPDATE test SET hide_me=true WHERE path #> 'Top.Science';
or
-- nuke the cosmology branch
DELETE FROM test WHERE path #> 'Top.Science.Cosmology';
If combined with the traditional "comment_id"/"parent_id" approach using stored procedures, I'm thinking you can get the best of both worlds. You can quickly traverse the comment tree in the database using your "path" and still ensure referential integrity via "comment_id"/"parent_id". I'm envisioning something like:
CREATE TABLE comments (
comment_id SERIAL PRIMARY KEY,
parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
thread_id int NOT NULL REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
path ltree NOT NULL,
comment_body text NOT NULL,
hide boolean not null default false
);
The path string for a comment look like be
<thread_id>.<parent_id_#1>.<parent_id_#2>.<parent_id_#3>.<my_comment_id>
Thus a root comment of thread "102" with a comment_id of "1" would have a path of:
102.1
And a child whose comment_id is "3" would be:
102.1.3
A some children of "3" having id's of "31" and "54" would be:
102.1.3.31
102.1.3.54
To hide the node "3" and its kids, you'd issue this:
UPDATE comments SET hide=true WHERE path #> '102.1.3';
I dunno though--it might add needless overhead. Plus I don't know how well maintained ltree is.
Your current design is basically fine for small hierarchies (less than thousand items)
If you want to fetch on a certian level or depth, add a 'level' item to your structure and compute it as part of the save
If performance is an issue use a decent cache
I'd add the following new fields to the above tabel:
thread_id: identifier for all comments attached to a specific object
date: the comment date (allows fetching the comments in order)
rank: the comment rank (allows fetching the comment order by ranking)
Using these fields you'll be able to:
fetch all comments in a thread in a single op
order comments in a thread either by date or rank
Unfortunately if you want to preserve your queries DB close to SQL standard you'll have to recreate the tree in memory. Some DBs are offering special queries for hierarchical data (f.e. Oracle)
./alex

Resources