【问题标题】:How to cleanly batch queries together in Gremlin如何在 Gremlin 中干净地批处理查询
【发布时间】:2021-10-22 07:37:04
【问题描述】:

我正在编写一个 GraphQL 解析器,它使用以下查询检索特定边的所有顶点(创建的返回标签人):

software {
   created {
     name
   }
}

对于找到的每个软件节点,这将解析为以下 Gremlin 查询:

g.V().hasLabel('software').has('name', 'ripple').in('created')

这会返回一个包含对象所有属性的结果:

{
    "result": [
        {
            "@type": "d",
            "@rid": "#24:0",
            "@version": 6,
            "@class": "person",
            "in_knows": [
                "#35:0"
            ],
            "name": "josh",
            "out_created": [
                "#32:0",
                "#33:0"
            ],
            "age": 32,
            "@fieldTypes": "in_knows=g,out_created=g"
        }
    ],
    "dbStats": {
        ...
    }
}

我意识到这会违反 GraphQL 的 N+1 查询,因此我尝试使用 Dataloader 模式将查询一起批处理。 (我也希望做属性选择,所以我没有要求数据库返回太多信息)

所以我正在尝试制作这样的查询:

g.V().union(
    __.hasLabel('software').has('name', 'ripple').
    project('parent', 'child').by('id').
      by(__.in('created').fold()),
    __.hasLabel('software').has('name', 'lop').
    project('parent', 'child').by('id').
      by(__.in('created').fold())
  )

但这会导致缺少道具并且只包含我想要的顶点的ID:

{
    "result": [
        {
            "parent": "ripple",
            "child": [
                "#24:0"
            ]
        },
        {
            "parent": "lop",
            "child": [
                "#22:0",
                "#23:0",
                "#24:0"
            ]
        }
    ],
    "dbStats": {
       ...
    }
}

我的问题是,如何让 Gremlin 查询返回找到的顶点的所有道具而不返回其他道具?我是否应该以这种方式进行批处理?

【问题讨论】:

  • 您如何调用 Gremlin 端点以及您使用的是哪个后端图形数据库?如果您使用 Gremlin 客户端,您将只能获取每个边和顶点的 ID 和标签。您需要明确请求所需的属性。
  • 使用使用 Gremlin 3.4.7 的 Orient DB 3.2.0。我只使用工作室资源管理器来发送值。我添加了 elementMap 来选择我想要的属性,但只检索第一个顶点。见gremlify.com/d3o3eazr58g
  • 我不确定 OrientDB 是如何工作的,但 Gremlify 示例对我有用,我希望它可以与启用 TinkerPop 的图形数据库一起使用。
  • 所以,我了解这个问题以及我所面临的问题。我在 gremlify 中给出的示例无法正常工作,因为它将 3 个结果展平为 1 个元素,以保持从 be(in('created) 返回的 TraversalSet 的基数。我不明白流只在一个一次一行,并且您不能像我尝试做的那样将更多行添加到一个 TraversalSet 集中。所以我将查询重写为一个选择。

标签: graphql gremlin


【解决方案1】:

对于其他阅读者,我试图编写的查询不起作用,因为在 .by(_.in('created') 中创建的 TraversalSet 无法从 List 转换为 ElementMap 作为流基数不会被强制执行。(我认为每行只能有一条记录?)

我的工作查询是复制每一行的键并指定所需的道具(下面的查询对于 ODB 中使用的 gremlin 3.3 是可以的,否则如果你有

g.V().union(
    __.hasLabel('software').has('name', 'ripple').
      as('parent').
    in('created').as('child').
      select('parent', 'child').
      by(values('name')).
      by(properties('id', 'name', 'age').
        group().by(__.key()).
          by(__.value())),
    __.hasLabel('software').has('name', 'lop').
      as('parent').
    in('created').as('child').
      select('parent', 'child').
      by(values('name')).
      by(properties('id', 'name', 'age').
        group().by(__.key()).
          by(__.value()))
  )

这样你就会得到这样的结果:

{"data": [
  {
    "parent": "ripple",
    "child": {
      "id": 5717,
      "name": "josh",
      "age": 32
    }
  },
  {
    "parent": "lop",
    "child": {
      "id": 5709,
      "name": "peter",
      "age": 35
    }
  },
  {
    "parent": "lop",
    "child": {
      "id": 5713,
      "name": "marko",
      "age": 29
    }
  },
  {
    "parent": "lop",
    "child": {
      "id": 5717,
      "name": "josh",
      "age": 32
    }
  }
]
}

这将允许您创建一个查找,将“lop”和“ripple”的所有结果连接到数组中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    相关资源
    最近更新 更多