OrientDB:获取顶点子查询之间的边
OrientDB: Getting edges between subqueries of vertices
请指教:
- 我只需要获取一个顶点(艺术家)和一组顶点(按创建日期排序的文章)之间的边。
我现在在做什么:
A. 比如说,麦当娜的记录:
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
乙。获取关于她的 2 篇最新文章:
SELECT expand(in("AboutArtist")[content_type="article"]) FROM Artist WHERE title="Madonna" ORDER BY created DESC LIMIT 2
我使用 "content_type" 因为我有 2 个指向艺术家的节点类型:文章和画廊。我只需要文章。
预期结果:艺术家和关于她的文章之间的边数组(2 篇文章按创建日期排序)。
- 此外,对于相同的用例,请告知正确的遍历以将所有内容放在一起:
麦当娜的唱片
和她的 2 篇文章(根据上面的查询)
以及它们之间的边
谢谢!
D.
在给出答案之前,我会澄清一些你似乎有的误解。
- 我认为您使用的是常规边,而不是轻量级边?您不能 return 查询中的轻量级边缘,因为它没有物理记录。因此,如果您确实需要边缘记录,因为它们本身有一些字段,请确保正确配置数据库。
- 当您执行
expand(in('SomeEdge'))
时,它将跟随 link 到下一条记录。在轻量级边的情况下,这将是一个顶点,它将被 returned。在边缘记录的情况下,它将跟随 link 到下一条记录(可能是顶点,除非你 link 边缘到边缘),然后 return 该记录。因此如果你想得到边缘记录,你需要使用inE()
,而不是in()
。
- 更进一步,当你有一条边缘记录时(即你使用
inE()
扩展了一个字段),那么你可以通过field/link到达下一条记录[=18] =],或者outV()
函数(假设边缘只有1个link,它会return那1条记录)。您将在我的回答中看到 out
字段。
[content_type="article"]
正在检查记录中名为 'content_type' 的字段,这会导致加载记录(并可能从结果中丢弃,因此加载 'wasted')。相反,如果您有特定的 class 文章和图库,您应该使用它们来过滤 [@class=Article]
。我相信 OrientDB 可以根据作为 rid 一部分的集群 ID 推断 class,因此它不必加载记录来过滤它。
- 除了上一点,与其让 link 的画廊和文章有 1 个边缘(目前你有 "AboutArtist"),为什么不为每个创建一个特定的边缘,即 'hasArticle' 和 'hasGallery'?这样你根本不需要过滤记录。
所以这是获取 2 个最新文章边缘的查询。
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM Artist
WHERE title="Madonna"
ORDER BY out.created DESC
LIMIT 2
如果您有 2 位或更多位名为 Madonna 的艺术家,该查询将无法按预期运行,因为它将获得所有 Madonna 的所有边缘,以及 return 最近的 2 位,其中可能不适合您真正想要的麦当娜。因此,我将 'nest' 找到麦当娜的查询,并将其限制为 1(假设它是正确的)。看起来顺序和限制在你这样做的时候作用不一样,所以你需要嵌套两次。
SELECT
FROM (
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM (
SELECT
FROM Artist
WHERE title="Madonna"
LIMIT 1
)
)
ORDER BY out.created DESC
LIMIT 2
所以最内层查询获取麦当娜,'middle' 查询获取麦当娜的边,外层查询对这些边进行排序和限制。
你的最后一题有点难。从 1 Madonna 遍历,return 遍历所有边和 link 顶点非常容易;
TRAVERSE inE('AboutArtist'), out
FROM (
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
)
这 return 所有 AboutArtist 边缘,以及所有文章和画廊。将其限制为我们在上面发现的 2 个边被证明有点困难。我找不到优雅的解决方案,但我找到了一个 none the less.
TRAVERSE in, out
FROM (
SELECT
FROM (
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM (
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
)
)
ORDER BY out.created DESC
LIMIT 2
)
我所做的只是嵌套上面的查询,找到 2 条边,然后遍历边的进出 links,从而 returning 艺术家和 2 篇文章。结果的顺序与遍历 artist->edge->article 时的顺序不同,但我怀疑顺序是否重要。
请指教:
- 我只需要获取一个顶点(艺术家)和一组顶点(按创建日期排序的文章)之间的边。
我现在在做什么: A. 比如说,麦当娜的记录:
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
乙。获取关于她的 2 篇最新文章:
SELECT expand(in("AboutArtist")[content_type="article"]) FROM Artist WHERE title="Madonna" ORDER BY created DESC LIMIT 2
我使用 "content_type" 因为我有 2 个指向艺术家的节点类型:文章和画廊。我只需要文章。
预期结果:艺术家和关于她的文章之间的边数组(2 篇文章按创建日期排序)。
- 此外,对于相同的用例,请告知正确的遍历以将所有内容放在一起: 麦当娜的唱片 和她的 2 篇文章(根据上面的查询) 以及它们之间的边
谢谢! D.
在给出答案之前,我会澄清一些你似乎有的误解。
- 我认为您使用的是常规边,而不是轻量级边?您不能 return 查询中的轻量级边缘,因为它没有物理记录。因此,如果您确实需要边缘记录,因为它们本身有一些字段,请确保正确配置数据库。
- 当您执行
expand(in('SomeEdge'))
时,它将跟随 link 到下一条记录。在轻量级边的情况下,这将是一个顶点,它将被 returned。在边缘记录的情况下,它将跟随 link 到下一条记录(可能是顶点,除非你 link 边缘到边缘),然后 return 该记录。因此如果你想得到边缘记录,你需要使用inE()
,而不是in()
。 - 更进一步,当你有一条边缘记录时(即你使用
inE()
扩展了一个字段),那么你可以通过field/link到达下一条记录[=18] =],或者outV()
函数(假设边缘只有1个link,它会return那1条记录)。您将在我的回答中看到out
字段。 [content_type="article"]
正在检查记录中名为 'content_type' 的字段,这会导致加载记录(并可能从结果中丢弃,因此加载 'wasted')。相反,如果您有特定的 class 文章和图库,您应该使用它们来过滤[@class=Article]
。我相信 OrientDB 可以根据作为 rid 一部分的集群 ID 推断 class,因此它不必加载记录来过滤它。- 除了上一点,与其让 link 的画廊和文章有 1 个边缘(目前你有 "AboutArtist"),为什么不为每个创建一个特定的边缘,即 'hasArticle' 和 'hasGallery'?这样你根本不需要过滤记录。
所以这是获取 2 个最新文章边缘的查询。
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM Artist
WHERE title="Madonna"
ORDER BY out.created DESC
LIMIT 2
如果您有 2 位或更多位名为 Madonna 的艺术家,该查询将无法按预期运行,因为它将获得所有 Madonna 的所有边缘,以及 return 最近的 2 位,其中可能不适合您真正想要的麦当娜。因此,我将 'nest' 找到麦当娜的查询,并将其限制为 1(假设它是正确的)。看起来顺序和限制在你这样做的时候作用不一样,所以你需要嵌套两次。
SELECT
FROM (
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM (
SELECT
FROM Artist
WHERE title="Madonna"
LIMIT 1
)
)
ORDER BY out.created DESC
LIMIT 2
所以最内层查询获取麦当娜,'middle' 查询获取麦当娜的边,外层查询对这些边进行排序和限制。
你的最后一题有点难。从 1 Madonna 遍历,return 遍历所有边和 link 顶点非常容易;
TRAVERSE inE('AboutArtist'), out
FROM (
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
)
这 return 所有 AboutArtist 边缘,以及所有文章和画廊。将其限制为我们在上面发现的 2 个边被证明有点困难。我找不到优雅的解决方案,但我找到了一个 none the less.
TRAVERSE in, out
FROM (
SELECT
FROM (
SELECT expand(inE('AboutArtist')[out.@class='Article'])
FROM (
SELECT FROM Artist WHERE title="Madonna" LIMIT 1
)
)
ORDER BY out.created DESC
LIMIT 2
)
我所做的只是嵌套上面的查询,找到 2 条边,然后遍历边的进出 links,从而 returning 艺术家和 2 篇文章。结果的顺序与遍历 artist->edge->article 时的顺序不同,但我怀疑顺序是否重要。