Gremlin 找到最高匹配
Gremlin find highest match
我打算使用图形数据库 (AWS Neptune),它可以作为一种知识库使用 Gremlin 进行查询。知识库将用作具有多个特征的实体的分类工具。为简单起见,在此示例中,我使用几何形状来编码我的实体的属性。假设我想对与正方形、三角形和圆形相关的点进行分类。我在图表中绘制了点与可能的正方形、三角形和圆形的不同可能关系,如下图所示。
创建于:
g.addV('Square').property(id, 'S_A')
.addV('Square').property(id, 'S_B')
.addV('Circle').property(id, 'C_A')
.addV('Triangle').property(id, 'T_A')
.addV('Triangle').property(id, 'T_B')
.addV('Point').property(id, 'P1')
.addV('Point').property(id, 'P2')
.addV('Point').property(id, 'P3')
g.V('P1').addE('Has_Triangle').to(g.V('T_B'))
g.V('P2').addE('Has_Triangle').to(g.V('T_A'))
g.V('P1').addE('Has_Square').to(g.V('S_A'))
g.V('P2').addE('Has_Square').to(g.V('S_A'))
g.V('P2').addE('Has_Circle').to(g.V('C_A'))
g.V('P3').addE('Has_Circle').to(g.V('C_A'))
g.V('P3').addE('Has_Square').to(g.V('S_B'))
不同的实体例如点、正方形、三角形、圆形。
所以我的最终目标是找到满足最多条件的点。例如
g.V().hasLabel('Point').where(and(
out('Has_Triangle').hasId('T_A'),
out('Has_Circle').hasId('C_A'),
out('Has_Square').hasId('S_A')
))
// ==>v[P2]
上面的查询非常适用于将具有属性 (T_A,S_A,C_A)
的点 (a) 分别分类为 Point 2
(P2) 类型。但是,如果我必须使用相同的查询来对具有属性 (C_A,S_B,T_X)
的点进行分类,例如:
g.V().hasLabel('Point').where(and(
out('Has_Triangle').hasId('T_X'),
out('Has_Circle').hasId('C_A'),
out('Has_Square').hasId('S_B')
))
查询无法将此点分类为点 3 (P3),因为在 KB 中没有 P3
的已知 Triangle
属性。
有没有一种方法可以表示 returns 具有最高 匹配度 的顶点,在本例中为 P3?
提前致谢。
编辑
目前解决此问题的最佳方法是为不存在的 KB 属性设置标记值。然后修改查询以匹配每个精确的 属性 或标记值。但这意味着如果我在将来添加一个 属性 的新 "type" 到一个点,例如点 Has_Hexagon,比我需要将哨兵六边形添加到我的图形的所有点。
编辑 2
添加了创建示例数据的 Gremlin 脚本
您可以使用 choose()
步骤为每个匹配增加一个计数器 (sack
),然后按计数器值排序(降序)并选择第一个(最高匹配)。
gremlin> g.withSack(0).V().hasLabel('Point').
choose(out('Has_Triangle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Circle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Square').hasId('T_A'), sack(sum).by(constant(1))).
order().
by(sack(), decr).
limit(1)
==>v[P2]
gremlin> g.withSack(0).V().hasLabel('Point').
choose(out('Has_Triangle').hasId('T_X'), sack(sum).by(constant(1))).
choose(out('Has_Circle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Square').hasId('S_B'), sack(sum).by(constant(1))).
order().
by(sack(), decr).
limit(1)
==>v[P3]
上述查询中的每个 choose()
步骤都可以读作 if (condition) increment-counter
。在任何情况下,无论是否满足条件,原始顶点 (Point
) 将由 choose
步发出。
我打算使用图形数据库 (AWS Neptune),它可以作为一种知识库使用 Gremlin 进行查询。知识库将用作具有多个特征的实体的分类工具。为简单起见,在此示例中,我使用几何形状来编码我的实体的属性。假设我想对与正方形、三角形和圆形相关的点进行分类。我在图表中绘制了点与可能的正方形、三角形和圆形的不同可能关系,如下图所示。
创建于:
g.addV('Square').property(id, 'S_A')
.addV('Square').property(id, 'S_B')
.addV('Circle').property(id, 'C_A')
.addV('Triangle').property(id, 'T_A')
.addV('Triangle').property(id, 'T_B')
.addV('Point').property(id, 'P1')
.addV('Point').property(id, 'P2')
.addV('Point').property(id, 'P3')
g.V('P1').addE('Has_Triangle').to(g.V('T_B'))
g.V('P2').addE('Has_Triangle').to(g.V('T_A'))
g.V('P1').addE('Has_Square').to(g.V('S_A'))
g.V('P2').addE('Has_Square').to(g.V('S_A'))
g.V('P2').addE('Has_Circle').to(g.V('C_A'))
g.V('P3').addE('Has_Circle').to(g.V('C_A'))
g.V('P3').addE('Has_Square').to(g.V('S_B'))
不同的实体例如点、正方形、三角形、圆形。
所以我的最终目标是找到满足最多条件的点。例如
g.V().hasLabel('Point').where(and(
out('Has_Triangle').hasId('T_A'),
out('Has_Circle').hasId('C_A'),
out('Has_Square').hasId('S_A')
))
// ==>v[P2]
上面的查询非常适用于将具有属性 (T_A,S_A,C_A)
的点 (a) 分别分类为 Point 2
(P2) 类型。但是,如果我必须使用相同的查询来对具有属性 (C_A,S_B,T_X)
的点进行分类,例如:
g.V().hasLabel('Point').where(and(
out('Has_Triangle').hasId('T_X'),
out('Has_Circle').hasId('C_A'),
out('Has_Square').hasId('S_B')
))
查询无法将此点分类为点 3 (P3),因为在 KB 中没有 P3
的已知 Triangle
属性。
有没有一种方法可以表示 returns 具有最高 匹配度 的顶点,在本例中为 P3?
提前致谢。
编辑
目前解决此问题的最佳方法是为不存在的 KB 属性设置标记值。然后修改查询以匹配每个精确的 属性 或标记值。但这意味着如果我在将来添加一个 属性 的新 "type" 到一个点,例如点 Has_Hexagon,比我需要将哨兵六边形添加到我的图形的所有点。
编辑 2
添加了创建示例数据的 Gremlin 脚本
您可以使用 choose()
步骤为每个匹配增加一个计数器 (sack
),然后按计数器值排序(降序)并选择第一个(最高匹配)。
gremlin> g.withSack(0).V().hasLabel('Point').
choose(out('Has_Triangle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Circle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Square').hasId('T_A'), sack(sum).by(constant(1))).
order().
by(sack(), decr).
limit(1)
==>v[P2]
gremlin> g.withSack(0).V().hasLabel('Point').
choose(out('Has_Triangle').hasId('T_X'), sack(sum).by(constant(1))).
choose(out('Has_Circle').hasId('T_A'), sack(sum).by(constant(1))).
choose(out('Has_Square').hasId('S_B'), sack(sum).by(constant(1))).
order().
by(sack(), decr).
limit(1)
==>v[P3]
上述查询中的每个 choose()
步骤都可以读作 if (condition) increment-counter
。在任何情况下,无论是否满足条件,原始顶点 (Point
) 将由 choose
步发出。