0

尝试根据存储的字符串列表进行过滤时遇到问题。我想在 a 中构建这个列表,sideEffect()然后在后续的where(without()). 我期待一个用户列表,不包括user.a1在以下示例中,但user.a1包括在内。

g.V().hasLabel('user').sideEffect(hasId('user.a1').id().store('exclude')).where(id().is(without('exclude')))
[
    {
        "id": "user.a1",
        "label": "user",
        "type": "vertex"
    },
    {
        "id": "user.b1",
        "label": "user",
        "type": "vertex"
    },
    ...
]

我假设发生这种情况是因为 Gremlin 正在检查文字 string exclude,那么我如何让它检查存储在exclude变量中的 ID 呢?

例如,这有效:

g.V().hasLabel('user').sideEffect(hasId('user.a1').id().store('exclude')).where(id().is(without('user.a1')))
[
    {
        "id": "user.b1",
        "label": "user",
        "type": "vertex"
    },
    ...
]

编辑#1

尝试了stephen mallette建议的查询,但仍然没有得到我正在寻找的内容(也许在 CosmosDB 上不可能?)。

首先,显然filter不是 CosmosDB 上的可用功能:

g.V().hasLabel('user').
  sideEffect(hasId('user.a1').id().store('exclude')).
  filter(id().where(without('exclude')))

ExceptionType : GraphCompileException
ExceptionMessage : Gremlin Query Compilation
Error: Unable to find any method 'filter' @ line 1, column 81. 1
Error(s) Source : Microsoft.Azure.Graphs

第二个建议导致了一个空集,而第二个确实有效:

g.V().hasLabel('user').hasId('user.a1').
  aggregate('exclude').where(without('exclude'))
[]

g.V().hasLabel('user').
  sideEffect(hasId('user.a1').aggregate('exclude')).
  where(without('exclude'))
[
  {
    "id": "user.b1",
    "label": "user",
    "type": "vertex"
  },
  {
    "id": "user.b2",
    "label": "user",
    "type": "vertex"
  },
  ...
]

问题是我想使用它们的属性值过滤边缘。我的实际情况是,如果可能,我想将以下两个查询合并为一个:获取一组role顶点 ID,然后获取拥有其中一个角色并属于组子集的用户。(用户属于一个组,其角色 ID 在该组中设置为 user->groupbelongs_to边缘的属性。)

  1. 从角色层次结构中获取一组角色(role.2+所有父母)
g.V('role.2').store('roles').
  repeat(__.out('is_under')).emit().store('roles').
  select('roles').unfold().dedup().id()
[
    "role.2",
    "role.1"
]
  1. 在 group.B 或以上角色中获取具有上述角色的用户,并为他们提供不同角色的优势。
g.V('group.B').
  sideEffect(inE('belongs_to').
    has('role',within('role.1','role.2')).outV().store('users')).
  repeat(__.out('belongs_to')).emit().inE('belongs_to').
    has('role',within('role.1','role.2')).outV().store('users').
  select('users').unfold().addE('has').to(g.V('role.12'))
4

1 回答 1

0

这是一种方法:

g.V().hasLabel('user').
  sideEffect(hasId('user.a1').id().store('exclude')).
  filter(id().where(without('exclude')))

根据您创建的此示例与您的实际需求的匹配程度,或者是否因为您的问题而对其进行了简化,您可以更改一些内容。首先,您可能可以将其排除在外,sideEffect()因为store()它本身在技术上是一种副作用。其次,我想知道你是否真的想要store()一个 not aggregate()- 在继续过滤之前聚合会贪婪地收集所有 id:

g.V().hasLabel('user').
  hasId('user.a1').aggregate('exclude').by(id).
  filter(id().where(without('exclude')))

这当然有点“什么都不做”遍历,因为您已经过滤掉了您不想要的顶点hasId('user.a1'),但是我再次假设您在查询中的复杂性比您展示的要大. 我只是在指出 Gremlin 机制。

如果您不担心 id,您还可以进一步简化 - 顶点的相等性将与 id 相同,因此,以下内容与上述相同,但 Gremlin 步骤更少:

g.V().hasLabel('user').
  hasId('user.a1').aggregate('exclude').
  where(without('exclude'))

在询问有关 Gremlin 的问题时,最好添加一个生成示例数据的脚本,以便您可以获得符合您需求的经过测试的遍历。取而代之的是,我修改了“现代”图表以包含“重量”标签:

gremlin> g.addV('weight').property('v',1.0d)
==>v[13]

其中“v”值与玩具图现有边的两个权重值匹配。没有filter(),我认为你会进入这种模式:

gremlin> g.V().hasLabel('weight').
......1>   aggregate('w').by('v').
......2>   V().hasLabel('person').
......3>   outE().as('x').values('weight').
......4>   where(within('w')).
......5>   select('x')
==>e[8][1-knows->4]
==>e[10][4-created->5]
于 2019-03-12T11:01:09.883 回答