Returning an entire hierarchy (tree) using neo4j/cypher

倾然丶 夕夏残阳落幕 提交于 2019-12-07 11:09:07

问题


I have a graph which has a hierarchy of categories in it (similar to product categories on a shopping site, e.g., Clothing --> Mens --> Shirts --> Short Sleeve --> ...). I have a few use cases where I need to retrieve the entire hierarchy as a tree (nested ruby and/or javascript objects in this case). The only solution I've been able to come up with is to use NODES() to retrieve each unique path and then transform it into nested objects in the client. The performance of this is obviously a problem.

MATCH (store:Store),
      (store)-[:hasCategory]->(category:Category),
      categories=(category)-[:narrower*0..]->(:Category)
WHERE store.name = {name}
RETURN store, NODES(categories) AS categories

This returns result rows that are basically paths like:

[store, [category1, narrower_category1, narrower_category2, ...]]

What's the proper way to handle this in cypher without numerous trips back to the server or a massive fetch of data like the above query?


回答1:


What's the proper way to handle this in cypher without numerous trips back to the server or a massive fetch of data like the above query?

If you have a big hierarchy, you're going to have two basic options: get it a few levels of the hierarchy at a time (necessitating trips back to the server to get the next chunk) or you can fetch the whole thing like you're doing. I don't see a third option, so it's probably not possible to get a big hierarchy without either of those features.

What you're doing seems OK, but without further clarification your question seems impossible. What's wrong with what you're currently doing? How do you use the hierarchy and why do you need it all at once? E.g. if I was on amazon, they have a huge shopping hierarchy. Usually they'll only show me the top levels first (Menswear, Women's clothes, electronics). Then when I click on Electronics, they'll show me the next level ("E-book readers", "computer", etc). That's usually the way to go, IMHO - multiple trips to the database, one level of hierarchy at a time. This lends itself to a tree-view and AJAX calls on a web page. When the user expands the tree, you do an AJAX call back to the server, and populate the children.

Each call in the hierarchy would probably be:

MATCH (category:Category { id: "whatever user picked" })-[:narrower]->(children:Category)
RETURN children
ORDER BY children.name;

If this incremental approach (one level at a time) won't work for your use case, then you're back to fetching the whole thing, which inevitably will be "one massive fetch of data".




回答2:


I solved a similar problem with this query:

MATCH p=((s)-[*0..]->(x))
where id(s)=3
return x,id(x),id(startNode(last(relationships(p))))

Here s is the root node identified by its id. The result is a table with each node, its id and its parent's id. The root node has a parent id of null.

It shouldn't be hard to rebuild the hierarchy with this information.



来源:https://stackoverflow.com/questions/28120002/returning-an-entire-hierarchy-tree-using-neo4j-cypher

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!