作为新手,我在查询或DB模型上遇到了可能的故障。我想在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 EverymanNeo4jCypherQuery($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 EverymanNeo4jCypherQuery($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) 我的DB模型不正确,可能是我使用了另一个连接所有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)
因此,有些节点不是通过关系连接的,而是通过标签标记的。
当我使用下面的查询时,我会得到所有与子菜单相关的菜单选项。我该如何更改查询以获得所有主菜单选项(以及SUPPORT和HOME)和子菜单选项(如)
m.name s.name m:MAIN
ADMIN GROUPS trueADMIN USER trueBLOG DELETE trueBLOG CREATE trueBLOG EDIT trueHOME NULL trueSUPPORT NULL真
在SQL中,我使用了类似LEFT JOIN的东西,但在Cypher中,我不确定。OPTIONAL没有帮助,我想还有其他方法吗?
不确定你的数据是什么样子的,你的子菜单也有一个:MENU标签吗?
我可能会用:menu标记所有菜单节点,然后为:Main和:Sub 添加一个标签
然后你可以一次获取所有信息,即使是任意深度:
MATCH (m:Menu)-[:IS_PARENT]->(s:Sub)
RETURN m.name, s.name, m:Main
菜单名称、子菜单对和true(如果m是主菜单),否则为false()
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
这个返回根菜单中的所有路径使用根菜单名称,然后将所有子菜单名称作为一个数组按根菜单名称和路径的升序排列