【问题标题】:Jagged Result Array Gremlin Query锯齿状结果数组 Gremlin 查询
【发布时间】:2020-02-20 05:46:02
【问题描述】:

请您帮我编写一个查询,将遍历中的每个源顶点及其关联的边和顶点作为每个此类源顶点上的数组返回?简而言之,我需要一个包含 3 元组数组的结果集,每个元组的第 1 项是源顶点,第 2 项和第 3 项是关联数组。

谢谢!

编辑 1:扩展了图形数据并添加了我当前的问题查询。 编辑 2:改进的 Gremlin 示例图形代码(抱歉,认为没有人会真正运行它。)

示例图

g.addV("blueprint").property("name","Mall").
addV("blueprint").property("name","HousingComplex").
addV("blueprint").property("name","Airfield").
addV("architect").property("name","Tom").
addV("architect").property("name","Jerry").
addV("architect").property("name","Sylvester").
addV("buildingCategory").property("name","Civil").
addV("buildingCategory").property("name","Commercial").
addV("buildingCategory").property("name","Industrial").
addV("buildingCategory").property("name","Military").
addV("buildingCategory").property("name","Resnameential").
V().has("name","Tom").addE("designed").to(V().has("name","HousingComplex")).
V().has("name","Tom").addE("assisted").to(V().has("name","Mall")).
V().has("name","Jerry").addE("designed").to(V().has("name","Airfield")).
V().has("name","Jerry").addE("assisted").to(V().has("name","HousingComplex")).
V().has("name","Sylvester").addE("designed").to(V().has("name","Mall")).
V().has("name","Sylvester").addE("assisted").to(V().has("name","Airfield")).
V().has("name","Sylvester").addE("assisted").to(V().has("name","HousingComplex")).
V().has("name","Mall").addE("classification").to(V().has("name","Commercial")).
V().has("name","HousingComplex").addE("classification").to(V().has("name","Resnameential")).
V().has("name","Airfield").addE("classification").to(V().has("name","Civil"))

请注意,以上是我们数据的非常简化的呈现。

需要的查询结果

我需要将每个蓝图顶点作为基础,并将其关联的每个边/顶点作为数组。

我目前的解决方案

目前我执行这个非常繁琐的查询,获取蓝图并分配标签,获取架构师并分配标签,然后选择两个标签。解决方法还可以;但是,当我需要包含边或需要获取蓝图分类顶点(工业、军事、住宅、商业等)时,它会变得混乱。实际上,我需要为每个蓝图拉回的关联数据越多,我的解决方案就会变得越草率。

我当前的查询看起来像这样:

g.V().hasLabel("blueprint").as("blueprints").
outE().or(hasLabel("designed"),hasLabel("assisted")).inV().as("architects").
select("blueprints").coalesce(out("classification"),constant()).as("classifications").
select("blueprints","architects","classifications")

以上产生了很多重复。如果:blueprints 为 b,architects 为 a,classifications 为 c,则结果集包含 b * a * c 结果。我想要一个蓝图,其中包含一组相关的架构师和一组相关的分类(如果有的话)。

并发症

我正在尝试在一个查询中执行此操作,以便我可以从图表中获取所有蓝图数据以填充过滤列表。一旦我有了包含所有顶点、边及其属性的列表,用户就可以单击指向 blob 的链接、浏览到项目站点等。因此,我需要考虑分页和过滤,我会每次我得到一个新页面或过滤器发生变化时,我宁愿去一次服务器。

【问题讨论】:

  • 您可能想要添加更多关于您的数据的示例,以便查询变得更加相关,就像您将 industrialmilitary 引用为 blueprint 的类型一样,所以您可以延长它。您还可以提供一个查询示例以供使用,因此其他人不会遵循您的路径。
  • 我已经按要求完成了。
  • 请测试您的数据加载脚本。它不是一个有效的语法。最值得注意的问题是将“id”作为属性键与代表实际图形元素标识符的T.id 混合。此外,您的 addE() 语句不正确 - from()to() 调制器需要指向步骤标签或顶点(在某些情况下,您有后者“正确”但由于 T.id 问题我提到了他们将不返回任何顶点)。
  • 我已经按要求完成了。
  • 不确定是否有助于添加我正在寻找的结果是一组 3 元组,其中每个元组:第 1 项是蓝图,第 2 项是蓝图的架构师数组,第 3 项是蓝图的分类数组。

标签: gremlin azure-cosmosdb-gremlinapi


【解决方案1】:

我想出了一个答案;但是,它使查询的计算费用翻了两番。不确定这是否可以进一步优化。

g.V().hasLabel("blueprint").
project("blueprints","architects").
by().
by(outE().or(hasLabel("designed"),hasLabel("assisted")).inV().dedup().fold())

我刚刚解决了蓝图和架构师,但分类只需要另一个 by(...traversal...) 和投影标签。

我可能只需要在一个查询中获取蓝图,在并行查询中获取它们的每个关联项,然后将它们全部放在 API 中。这对于 API 数据层来说是非常糟糕的设计,但出于性能原因可能是必要的。

【讨论】:

  • 这个 outE().or(hasLabel("designed"),hasLabel("assisted")).inV() 可以简化为 out('designed','assisted') - 也许你的图形数据库没有正确优化 or()
  • 感谢您的建议;但是,它只减少了 0.4% 的处理。
  • 不确定您使用的是什么图形数据库,但大多数图形不会仅按标签优化顶点查找。大多数图表最终都会进行完整的图表扫描以找到它们。通常,遍历将从由索引标识的顶点或顶点的小子集开始。如果您正在进行全图扫描并且有很多“蓝图”顶点要找到,那么您需要遍历很多边来收集您想要的所有数据,我想我可以明白为什么它可能是“慢"。
  • 如帖子中所说,我使用的是简化版的数据,这必然意味着查询的简化版。将计算量翻四倍以执行 project()。
猜你喜欢
  • 2020-04-02
  • 1970-01-01
  • 2015-09-23
  • 2013-06-21
  • 2015-07-01
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多