作为新的首发,我坚持我的查询或数据库模型可能出现故障。我想在neo4j数据库中实现我的应用程序的菜单结构,以便从主/子菜单相关性中受益。
所以有MAIN和SUB选项,而MAIN可以有几个SUB但不能。
一个例子:
HOME (main)
ADMIN (main) - USER (sub)
DESK (main) - EDIT (sub)
- CREATE (sub)
a.s.o。
在创建节点时,我使用“is_parent”在MAIN和SUB节点之间建立关系。
所以我的第一个挑战是再次从DB中读取结构并构建一个相关的数组来构造菜单结构。
我在尝试:
# Identify all Menu-Options of the main Menu
$queryString = 'MATCH (main:MENU) RETURN main;';
$query = new Everyman\Neo4j\Cypher\Query($client, $queryString);
$result = $query->getResultSet();
foreach ($result as $row) {
# Echo for debug
echo '<hr>'.$row['main']->getProperty('name') . "<br>";
$query_sub = '
MATCH (main:MENU {name: "'.$row['main']->getProperty('name').'"})-[:is_parent]->sub:SUBMENU)
RETURN sub;
';
$query_sub = new Everyman\Neo4j\Cypher\Query($client, $query_sub);
$result_sub = $query_sub->getResultSet();
foreach ($result_sub as $row_sub) {
# echo for debug
echo 'SUB:'.$row_sub['sub']->getProperty('name') . "<br>";
}
}
但似乎我让每个菜单选项都加倍 - 好像我会遍历每个图表两次,因此我想
a)要么我不理解查询是正确的(最有可能因为这是我的第二次尝试) b)我的数据库模型不正确,可能会忽略连接所有MAIN MENU节点的另一个PARENT-NODE(现在它们没有连接,只有SUB连接到相关MAIN)。
我使用neo4jphp连接数据库。
非常感谢每一个提示。
谢谢!
P.S:
我为数据制作了这个模式作为一个例子(顺便说一句。也许有一种方法可以使查询更紧凑?):
create (home:MENU:MAIN { name: "HOME" })
create (admin:MENU:MAIN { name: "ADMIN" })
create (blog:MENU:MAIN { name: "BLOG" })
create (support:MENU:MAIN { name: "SUPPORT" })
create (user:MENU:SUB { name: "USER" })
create (groups:MENU:SUB { name: "GROUPS" })
create (local:MENU:SUB2 { name: "LOCAL" })
create (extern:MENU:SUB2 { name: "EXTERN" })
create (edit:MENU:SUB { name: "EDIT" })
create (create:MENU:SUB { name: "CREATE" })
create (delete:MENU:SUB { name: "DELETE" })
CREATE (admin)-[:IS_PARENT]->(user)
CREATE (admin)-[:IS_PARENT]->(groups)
CREATE (groups)-[:IS_PARENT]->(local)
CREATE (groups)-[:IS_PARENT]->(extern)
CREATE (blog)-[:IS_PARENT]->(edit)
CREATE (blog)-[:IS_PARENT]->(create)
CREATE (blog)-[:IS_PARENT]->(delete)
因此,有些节点没有按关系连接,但标有标签。
当我使用下面的查询时,我得到所有与子菜单有关系的菜单选项。如何更改查询以获取所有主菜单选项(因此支持和HOME)以及子菜单选项(如
)ADMIN GROUPS为true ADMIN USER为true 博客删除真实 博客创造真实 博客编辑是真的 HOME NULL true SUPPORT NULL true
在SQL中我使用了类似LEFT JOIN的东西,但在Cypher中我不确定。 OPTIONAL没有帮助,我猜还有另外一种方法吗?
答案 0 :(得分:1)
不确定您的数据是什么样的,您的子菜单是否还有:MENU标签?
我可能会使用以下菜单标记所有菜单节点,然后为:Main和:Sub
添加一个标签然后你可以一次性获取所有内容,即使是任意深度:
MATCH (m:Menu)-[:IS_PARENT]->(s:Sub)
RETURN m.name, s.name, m:Main
菜单名称,子菜单对,如果m是主菜单,则为true,否则为
MATCH (m:Main)
MATCH p = (m)-[:IS_PARENT*]->(s:Sub)
RETURN m.name, extract(n in tail(nodes(p)) | n.name) as menus
ORDER BY m.name ASC, length(p) asc
这个从根菜单返回所有路径 使用根菜单名称,然后将所有子菜单名称作为数组 按根菜单名称和路径的上升长度排序