CYPHER:NEO4JPHP避免双重结果(DB布局问题?)

时间:2014-11-01 18:29:15

标签: neo4j cypher neo4jphp

作为新的首发,我坚持我的查询或数据库模型可能出现故障。我想在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)
  1. 因此,有些节点没有按关系连接,但标有标签。

  2. 当我使用下面的查询时,我得到所有与子菜单有关系的菜单选项。如何更改查询以获取所有主菜单选项(因此支持和HOME)以及子菜单选项(如

    m.name s.name m:MAIN

    ADMIN GROUPS为true ADMIN USER为true 博客删除真实 博客创造真实 博客编辑是真的 HOME NULL true SUPPORT NULL true

  3. 在SQL中我使用了类似LEFT JOIN的东西,但在Cypher中我不确定。 OPTIONAL没有帮助,我猜还有另外一种方法吗?

1 个答案:

答案 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

这个从根菜单返回所有路径 使用根菜单名称,然后将所有子菜单名称作为数组 按根菜单名称和路径的上升长度排序