简体   繁体   English

Neo4J,如何查询分层数据/ PHP

[英]Neo4J, how to query hierarchical data / PHP

i created a category-structure in graph-database "neo4j". 我在图数据库“ neo4j”中创建了一个类别结构。 I have nodes and relationships, everything perfect. 我有节点和关系,一切都很完美。

I am using Neoxygen Neoclient for PHP to access the data. 我正在使用Neoxygen Neoclient for PHP访问数据。 How can I query the whole category-graph in an efficient way (including structure) from my root-element? 如何从根元素中高效查询整个类别图(包括结构)?

MATCH (a:`Category`{category_id:0})-[r:HAS_CHILD*]->(b:`Category`)
RETURN b,r

My desired structure in PHP is: - Root --- Category A -------- Subcategory AB --- Category B --- Category C -------- Subcategory CA ----------------- Subsubcategory CAA ... 我希望在PHP中使用以下结构:-根目录-A类--------子类别AB-B类-C类--------子类别CA ------ -----------子类别CAA ...

Any ideas? 有任何想法吗?

Thanks in advance. 提前致谢。

mr_g mr_g

It is totally feasible and user-friendly in Neoxygen's NeoClient. 在Neoxygen的NeoClient中,这完全可行且用户友好。

The first thing to make sure, is that you activate the response formatter : 首先要确保的是,您激活响应格式化程序:

$client = ClientBuilder::create()
   ->setAutoFormatResponse(true)
   ->addConnection(xxx...)
   ->build();

Secondly, concerning your query I would definitely set a depth limit to avoid memory behaviors depending of your graph connectedness : 其次,关于您的查询,我绝对会设置深度限制,以避免依赖于您的图形连接性的内存行为:

MATCH (a:`Category`{category_id:0})-[r:HAS_CHILD*..20]->(b:`Category`)
RETURN b,r

Then, you can send it with the client and benefit that the client will remap the results in a graph structure : 然后,您可以将其与客户端一起发送,并受益于客户端将结果重新映射为图结构:

$query = 'MATCH (a:`Category`{category_id:{id}})-[r:HAS_CHILD*..20]->(b:`Category`)'
RETURN b,r';
$children = $client->sendCypherQuery($q, ['id'=>0])->getResult()->getNodes();

Now, each node will know what he has as relationships and relationships know their start and end nodes, example : 现在,每个节点将知道他所拥有的关系,而关系又知道它们的起点和终点,例如:

$children are nodes in the first depth, so $children是第一个深度的节点,因此

$rels = $children->getOutboundRelationships();
$nodes = [];
foreach ($rels as $rel) {
  $nodes[] = $rel->getEndNode();
}

$nodes holds now all the nodes in depth 2. 现在$ nodes保留了深度为2的所有节点。

There is, currently, no method to get directly the connected nodes from a node object without getting first the relationship, maybe something I can add to the client. 当前,没有一种方法可以在不先获取关系的情况下直接从节点对象获取连接的节点,也许我可以将其添加到客户端。

Cypher returns tabular data so if you want to get a tree hierarchy the most efficient way is to return all of the paths from the root to the leaves. Cypher返回表格数据,因此,如果要获取树层次结构,最有效的方法是返回从根到叶的所有路径 A path is a collection/array of node-(relationship-node)* (that is it's an odd number of objects, always containing a node at each end with alternating nodes and relationships). 路径是节点-(关系节点)*的集合/数组(也就是说,它是奇数个对象,始终在两端包含一个节点,这些节点具有交替的节点和关系)。 Here is the cypher for how you would do that: 这是您如何执行此操作的密码:

MATCH path(a:`Category`{category_id:0})-[r:HAS_CHILD*]->(b:`Category`)
WHERE NOT(b-[:HAS_CHILD]->())
RETURN b,r

The WHERE clause ensures that you only return all of the paths to the leafs. WHERE子句可确保仅将所有路径返回给叶子。 You could return all categories in the tree which would give you the partial paths too, but all of those partial paths are contained in some longer path so you'd just end up returning more data than you need. 您可以返回树中的所有类别,这也将为您提供部分路径,但是所有这些部分路径都包含在更长的路径中,因此您最终将返回比需要的更多的数据。

Once you have the paths (I'm not sure what form they show up in Neoclient as I'm not a PHP guy) you can build a hierarchical data structure in memory from the results. 一旦有了路径(由于我不是PHP专家,所以我不确定它们会以什么形式出现在Neoclient中),您可以根据结果在内存中构建分层数据结构。 If I recall correctly the map/dictionary-type structure in PHP is an associative array. 如果我没记错的话,PHP中的map / dictionary-type结构是一个关联数组。

Schema: 架构:

Indexes
  ON :Category(category_id)   ONLINE (for uniqueness constraint) 

Constraints
  ON (category:Category) ASSERT category.category_id IS UNIQUE

Query: 查询:

MATCH(c:Category) RETURN c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM