neo4j 验证有序列表中的所有项是否由图中具有指定关系的节点按顺序表示的密码查询

chy5wohz  于 2023-03-29  发布在  其他
关注(0)|答案(1)|浏览(89)

我正在建模一个简单的文件系统,包含文件夹和文件。

(:Folder)<-[:IS_IN *]-(:Folder)<-[:IS_IN]-(:File)

用户可以给予我一个任意的路径/foo/bar/baz.txt。在这种情况下,图看起来像这样:

(:Folder {Name: '/'})<-[:IS_IN]-(:Folder {Name: 'Foo'})<-[:IS_IN]-(:Folder {Name: 'bar'})<-[:IS_IN]-(:File {Name: 'baz.txt'})

如果不知道用户将提供多长的路径,有没有好的方法来查询给定的路径是否在图中表示?如果我将路径分割成一个有序的文件夹名称列表,我可以编写一个查询,当且仅当它们以与列表相同的顺序存在时,返回节点吗?
简单地说,我可以对每个节点动态生成一个查询,但我不想生成动态查询。

vfh0ocws

vfh0ocws1#

假设你传递了这个$path参数,并且路径中的最后一个元素是一个文件:

"/foo/bar/baz.txt"

假设你的数据看起来像这样:

(:Folder {Name: '/'})<-[:IS_IN]-
  (:Folder {Name: 'foo'})<-[:IS_IN]-
    (:Folder {Name: 'bar'})<-[:IS_IN]-
      (:File {Name: 'baz.txt'})

这应该行得通:

WITH SPLIT($path, '/') AS p
WITH REVERSE(CASE WHEN p[0] = '' THEN ['/']+p[1..] ELSE p END) AS names
OPTIONAL MATCH (file:File {Name: names[0]})
RETURN REDUCE(s=file, n IN names[1..] |
  CASE WHEN s IS NOT NULL THEN [(s)-[:IS_IN]->(f1 {Name: n})|f1][0] END
) IS NOT NULL AS found

查询将返回是否找到$path中的路径。
它将$path字符串分解为文件夹和文件名的数组,反转它,然后optionally matches文件节点。我们使用OPTIONAL MATCH,以便查询总是返回一个值,然后,我们使用REDUCE函数循环遍历路径中剩余的文件夹,以验证每个所需的关系是否存在。我们使用模式理解在循环中执行匹配。

相关问题