通过 has Step 在图中检索信息的最佳方法是什么
what is the best way to retrive information in a graph through has Step
我正在使用带有 tinkerpop 插件的 titan graph db。使用 has 步骤检索顶点的最佳方法是什么?
假设 employeeId 是一个唯一的属性,它定义了一个唯一的以顶点为中心的索引。
是否通过label
即 g.V().has(标签,'employee').has('employeeId','emp123')
g.V().has('employee','employeeId','emp123')
(或)
直接根据 Unique 属性检索顶点是否更好?
即 g.V().has('employeeId','emp123')
这两种方法中哪一种最快更好?
第二个选项 g.V().has('employeeId','emp123')
更好,只要 属性 employeeId
已经 indexed 以获得更好的性能。
这是因为 gremlin 遍历中的每一步都充当过滤器。所以当你说:
g.V().has(label,'employee').has('employeeId','emp123')
您首先找到标签为 employee
的所有顶点,然后从员工顶点找到 emp123
.
使用 g.V().has('employeeId','emp123')
复合索引可以让您直接转到正确的顶点。
编辑:
正如 Daniel 在他的回答中指出的那样,Titan 实际上足够聪明,不会访问所有员工并立即利用索引。所以在这种情况下,遍历之间似乎没有什么区别。我个人喜欢使用没有标签的直接全局索引(即第一次遍历),但这只是使用 Titan 时的偏好,我喜欢将步骤和过滤器保持在最低限度。
首先,您有 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')
不是 select 所有员工。 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 的唯一方法,因为我们完全摆脱了跨越所有类型顶点的 全局索引 。起初我真的不喜欢这个决定,但同时我不得不承认这样更干净。
我正在使用带有 tinkerpop 插件的 titan graph db。使用 has 步骤检索顶点的最佳方法是什么?
假设 employeeId 是一个唯一的属性,它定义了一个唯一的以顶点为中心的索引。
是否通过label 即 g.V().has(标签,'employee').has('employeeId','emp123') g.V().has('employee','employeeId','emp123')
(或) 直接根据 Unique 属性检索顶点是否更好? 即 g.V().has('employeeId','emp123')
这两种方法中哪一种最快更好?
第二个选项 g.V().has('employeeId','emp123')
更好,只要 属性 employeeId
已经 indexed 以获得更好的性能。
这是因为 gremlin 遍历中的每一步都充当过滤器。所以当你说:
g.V().has(label,'employee').has('employeeId','emp123')
您首先找到标签为 employee
的所有顶点,然后从员工顶点找到 emp123
.
使用 g.V().has('employeeId','emp123')
复合索引可以让您直接转到正确的顶点。
编辑:
正如 Daniel 在他的回答中指出的那样,Titan 实际上足够聪明,不会访问所有员工并立即利用索引。所以在这种情况下,遍历之间似乎没有什么区别。我个人喜欢使用没有标签的直接全局索引(即第一次遍历),但这只是使用 Titan 时的偏好,我喜欢将步骤和过滤器保持在最低限度。
首先,您有 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')
不是 select 所有员工。 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 的唯一方法,因为我们完全摆脱了跨越所有类型顶点的 全局索引 。起初我真的不喜欢这个决定,但同时我不得不承认这样更干净。