我正在使用titan graph db和tinkerpop插件。使用has step检索顶点的最佳方法是什么?
假设employeeId是一个唯一属性,它定义了一个唯一的以顶点为中心的索引。
是通过标签吗? 即g.V()。has(label,'employee')。has('employeeId','emp123') g.V()。具有( '雇员', 'EMPLOYEEID', 'emp123')
(或) 最好直接根据Unique属性检索顶点吗? 即g.V()。has('employeeId','emp123')
两者中哪一个是最快捷的方式?
答案 0 :(得分:3)
首先,您有2个选项来创建索引:
mgmt.buildIndex('byEmployeeId', Vertex.class).addKey(employeeId).buildCompositeIndex()
mgmt.buildIndex('byEmployeeId', Vertex.class).addKey(employeeId).indexOnly(employee).buildCompositeIndex()
对于选项1,您要使用哪个查询并不重要。对于选项2,必须使用g.V().has('employee','employeeId','emp123')
。
请注意,g.V().hasLabel('employee').has('employeeId','emp123')
NOT 将首先选择所有员工。 Titan足够智能,可以应用那些可以首先利用索引的过滤条件。
我想指出的另一件事是:indexOnly()
的重点是允许在不同类型的顶点之间共享属性。因此,不是调用属性employeeId
,而是将其称为uuid
,并将其用于雇主,公司等:
mgmt.buildIndex('employeeById', Vertex.class).addKey(uuid).indexOnly(employee).buildCompositeIndex()
mgmt.buildIndex('employerById', Vertex.class).addKey(uuid).indexOnly(employer).buildCompositeIndex()
mgmt.buildIndex('companyById', Vertex.class).addKey(uuid).indexOnly(company).buildCompositeIndex()
您的查询将始终具有此模式:g.V().has('<label>','<prop-key>','<prop-value>')
。这实际上是进入DSE Graph的唯一方法,因为我们完全摆脱了跨越所有类型顶点的全局索引。起初我真的不喜欢这个决定,但同时我必须同意这个更清洁。
答案 1 :(得分:1)
只要属性g.V().has('employeeId','emp123')
为indexed以获得更好的效果,第二个选项employeeId
就会更好。
这是因为gremlin遍历中的每个步骤都是一个过滤器。所以当你说:
g.V().has(label,'employee').has('employeeId','emp123')
首先转到标签为employee
的所有顶点,然后转到您找到emp123
的员工顶点。
使用g.V().has('employeeId','emp123')
复合索引可以直接转到正确的顶点。
修改强>
正如Daniel在回答中所指出的那样,Titan实际上足够聪明,不会访问所有员工并立即利用索引。所以在这种情况下,似乎遍历之间几乎没有区别。我个人赞成使用没有标签的直接全局索引(即第一次遍历),但这只是使用Titan时的偏好,我喜欢将步骤和过滤器保持在最低限度。