【问题标题】:CYPHER: NEO4JPHP Avoiding double result (issue with DB layout?)CYPHER:NEO4JPHP 避免双重结果(数据库布局问题?)
【发布时间】:2014-11-01 18:29:14
【问题描述】:

作为新手,我在查询或数据库模型上遇到了可能失败的问题。我想在 neo4j 数据库中实现我的应用程序的菜单结构,以便从主/子菜单相关性中受益。

所以有 MAIN 和 SUB 选项,而 MAIN 可以有多个 SUB,但不能。

一个例子:

HOME (main)
ADMIN (main) - USER (sub)
DESK (main)  - EDIT (sub)
             - CREATE (sub)

a.s.o.

在创建节点时,我使用“is_parent”在 MAIN 和 SUB 节点之间建立关系。

所以我的第一个挑战是再次从数据库中找到读取结构并构建相关数组来构建菜单结构。

我在尝试:

# 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) 我的 DB 模型不正确,可能错过了另一个连接所有 MAIN MENU 节点的 PARENT-NODE(现在它们没有连接,只有 SUB 连接到相关的 MAIN)。

我使用 neo4jphp 连接数据库。

每一个提示都非常感谢。

谢谢!

附注:

我为数据制作了这个架构作为示例(顺便说一句。也许有一种方法可以使查询更紧凑?):

    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. 当我使用下面的查询时,我会得到与子菜单相关的所有菜单选项。我将如何更改查询以获取所有主菜单选项(所以 SUPPORT 和 HOME 也是如此)以及 sub.menu-options 之类的

    m.name s.name m:MAIN

    管理组真 管理员用户真 博客删除真 博客创建真 博客编辑真 主页 NULL 真 支持 NULL 真

在 SQL 中,我使用了类似 LEFT JOIN 的东西,但在 Cypher 中我不确定。 OPTIONAL 没有帮助,我想还有其他方法吗?

【问题讨论】:

    标签: neo4j cypher neo4jphp


    【解决方案1】:

    不确定您的数据是什么样的,您的子菜单是否也有 :MENU 标签?

    我可能会用 :Menu 标记所有菜单节点,然后为 :Main 和 :Sub 附加一个标签

    然后您可以一次性获取所有内容,即使是任意深度:

    MATCH (m:Menu)-[:IS_PARENT]->(s:Sub)
    RETURN m.name, s.name, m:Main
    

    菜单、子菜单对的名称,如果 m 是主菜单则为 true,否则为 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
    

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

    【讨论】:

    • 你好迈克尔,非常感谢你的帮助。我在我的问题中添加了菜单数据的测试用例(感谢带有第二个子标签的提示),现在我正在尝试获取所有主菜单选项和相关的子选项 - 非常感谢任何提示。非常感谢。
    • 取决于您对选项的建模方式,作为菜单项上的数组属性或作为完整节点,在后一种情况下,您只需使用 OPTIONAL MATCH (s)-[:OPTIONS]-&gt;(o:Option) 扩展匹配
    猜你喜欢
    • 2018-10-06
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 1970-01-01
    相关资源
    最近更新 更多