后续查询需要哪些索引以避免全图扫描?

Which indexes do I need for following query to avoid a full-graph scan?

以下查询应该 return 最多 limit 个标签为 REPOSITORY 的顶点,这些顶点在 minLastUpdated 之前最后更新并且不属于类型 FILE_UPLOAD,除非设置了 NEEDS_UPDATE 标志。

g.V()
    .hasLabel(VertexLabel.REPOSITORY.name())
    .has(PropertyKey.INDEXED_LABEL.name(), VertexLabel.REPOSITORY.name())
    .has(PropertyKey.LAST_UPDATED.name(), P.lt(minLastUpdated))
    .or(__.not(__.has(PropertyKey.TYPE.name(), RepositoryType.FILE_UPLOAD.name())),
        __.has(PropertyKey.NEEDS_UPDATE.name(), true))
    .limit(limit);

为了避免全图扫描,我在属性 INDEXED_LABELTYPENEEDS_UPDATE 上创建了以下索引,一个结合了所有这三个索引和一个混合索引的复合索引:

//By Label
mgmt.buildIndex("byIndexedLabel", Vertex.class)
    .addKey(indexedLabelKey)
    .buildCompositeIndex();

//By Type
mgmt.buildIndex("byType", Vertex.class)
    .addKey(typeKey)
    .buildCompositeIndex();

//By Needs Update
mgmt.buildIndex("byNeedsUpdate", Vertex.class)
    .addKey(needsUpdateKey)
    .buildCompositeIndex();

//Combination of the three
mgmt.buildIndex("byIndexedLabelTypeAndNeedsUpdate", Vertex.class)
    .addKey(indexedLabelKey)
    .addKey(typeKey)
    .addKey(needsUpdateKey)
    .buildCompositeIndex();

//Mixed Index
mgmt.buildIndex("repositoryByTypeAndLastUpdated", Vertex.class)
    .addKey(indexedLabelKey, Mapping.STRING.asParameter())
    .addKey(lastUpdatedKey)
    .indexOnly(repositoryLabel)
    .buildMixedIndex("search");

然而,在执行查询时,我收到此警告:

WARN  - StandardTitanTx: Query requires iterating over all vertices [()]. For better performance, use indexes

旁注

环境

感谢您提出任何建议。

只有PropertyKey.INDEXED_LABEL.name()PropertyKey.LAST_UPDATED.name()相关,其他属性不能用于索引查找。也就是说,创建搜索索引是有意义的,因为 a) 您有多个属性,b) 其中一个具有范围条件:P.lt(minLastUpdated)(没有其他索引可以回答范围查询,并且具有多个多个属性众所周知,复合索引迟早会引起麻烦)。创建涵盖两个属性的单个索引以获得最佳性能。

mgmt.buildIndex('repositoryByTypeAndLastUpdated', Vertex.class).
    addKey(indexedLabelKey, Mapping.STRING.asParameter()).
    addKey(lastUpdatedKey).indexOnly(repositoryLabel).buildMixedIndex("search")

更新:

INDEXED_LABEL 实际上不可索引,或者更确切地说不应被索引,因为它似乎只是存储为 属性 的顶点标签的副本。下面是一个完整的示例,它不会给您任何关于全面扫描的警告。

gremlin> graph = TitanFactory.open("conf/titan-berkeleyje-es.properties")
==>standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley]
gremlin> g = graph.traversal()
==>graphtraversalsource[standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley], standard]
gremlin> m = graph.openManagement()
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@10a0a1e
gremlin> repository = m.makeVertexLabel("repository").make()
==>repository
gremlin> lastUpdated = m.makePropertyKey("lastUpdated").dataType(Long.class).make()
==>lastUpdated
gremlin> needsUpdate = m.makePropertyKey("needsUpdate").dataType(Boolean.class).make()
==>needsUpdate
gremlin> type = m.makePropertyKey("type").dataType(String.class).make()
==>type
gremlin> m.buildIndex("repositoryByLastUpdated", Vertex.class).
gremlin>   addKey(lastUpdated).indexOnly(repository).buildMixedIndex("search")
==>repositoryByLastUpdated
gremlin> m.commit()
==>null

gremlin> g.V().has("repository", "lastUpdated", lt(System.currentTimeMillis())).
gremlin>   or(has("type", neq("FILE UPLOAD")), has("needsUpdate", true)).limit(10)
gremlin> 

我的图表中没有数据,但会显示带有或 w/o 数据的警告。