Gremlin 小精灵找到最高匹配

Gremlin 小精灵找到最高匹配,gremlin,tinkerpop,tinkerpop3,amazon-neptune,Gremlin,Tinkerpop,Tinkerpop3,Amazon Neptune,我计划使用一个图形数据库(AWS Neptune),可以用Gremlin作为一种知识库进行查询。知识库将用作具有多个特征的实体的分类工具。为简单起见,在本例中,我使用几何图形对实体的属性进行编码。假设我想对与正方形、三角形和圆相关的点进行分类。我已经绘制了点与图中可能的正方形、三角形和圆形的不同可能关系的蓝图,如下图所示 创建时使用: g.addV('Square').property(id, 'S_A') .addV('Square').property(id, 'S_B') .add

我计划使用一个图形数据库(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\u a、S\u a、C\u a)
的点(a)分类为
点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
属性

有没有一种方法可以表达一个查询,返回匹配度最高的顶点,在本例中是P3

先谢谢你

编辑

到目前为止,解决这个问题的最好办法是为不存在的KB属性设置sentinel值。然后修改查询以匹配每个精确属性或sentinel值。但这意味着,如果我在将来向一个点添加一个新的“类型”属性(例如,一个点具有_六边形),那么我需要向图形的所有点添加sentinel六边形

编辑2


添加了创建样本数据的Gremlin脚本

您可以使用
choose()
步骤为每个匹配增加一个计数器(
sack
),然后按计数器值排序(降序)并选择第一个(最高匹配)


上述查询中的每个
choose()
步骤都可以理解为
if(condition)increment counter
。在任何情况下,无论条件是否满足,原始顶点(
)都将由
选择
-步骤发出。

能否请您提供一个创建一些示例数据的Gremlin脚本?这里是一个示例是的,当然,请检查我的最新编辑。嗨,丹尼尔,感谢您的回复,除了一个用例外,查询可以正常工作。如果点具有
(T_a,S_a,C_B)
,则查询将返回
P2
,但情况不应如此,因为
P2
有三个条件。因此,我将对其进行修改,以检查
sack
sum是否与顶点的输出边数匹配。
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]