JanusGraph索引学习笔记

Indexing for Better Performance

JanusGraph supports two different kinds of indexing to speed up query processing: graph indexes and vertex-centric indexes. Most graph queries start the traversal from a list of vertices or edges that are identified by their properties. Graph indexes make these global retrieval operations efficient on large graphs. Vertex-centric indexes speed up the actual traversal through the graph, in particular when traversing through vertices with many incident edges.

索引以获得更好的性能 JanusGraph支持两种不同类型的索引以加快查询处理:图形索引和以顶点为中心的索引。大多数图形查询从顶点或边的列表开始遍历,这些顶点或边由属性标识。图索引使这些全局检索操作在大型图上高效。以顶点为中心的索引加快了实际遍历图形的速度,特别是在遍历具有许多入射边的顶点时。

Graph Index

Graph indexes are global index structures over the entire graph which allow efficient retrieval of vertices or edges by their properties for sufficiently selective conditions. For instance, consider the following queries

图形索引 图索引是整个图的全局索引结构,它允许在充分选择的条件下,通过顶点或边的属性来有效地检索它们。例如,考虑以下查询

g.V().has('name', 'hercules') 
g.E().has('reason', textContains('loves'))

第一个查询要求所有名为hercules的顶点。第二个要求所有的边缘,其中属性原因包含爱这个词。如果没有图索引来回答这些查询,则需要对图中的所有顶点或边进行全面扫描,以找到符合给定条件的顶点或边,这对于大型图来说是非常低效和不可行的。

JanusGraph distinguishes between two types of graph indexes: composite and mixed indexes. Composite indexes are very fast and efficient but limited to equality lookups for a particular, previously-defined combination of property keys. Mixed indexes can be used for lookups on any combination of indexed keys and support multiple condition predicates in addition to equality depending on the backing index store.

Both types of indexes are created through the JanusGraph management system and the index builder returned by JanusGraphManagement.buildIndex(String, Class) where the first argument defines the name of the index and the second argument specifies the type of element to be indexed (e.g. Vertex.class). The name of a graph index must be unique. Graph indexes built against newly defined property keys, i.e. property keys that are defined in the same management transaction as the index, are immediately available. The same applies to graph indexes that are constrained to a label that is created in the same management transaction as the index. Graph indexes built against property keys that are already in use without being constrained to a newly created label require the execution of a reindex procedure to ensure that the index contains all previously added elements. Until the reindex procedure has completed, the index will not be available. It is encouraged to define graph indexes in the same transaction as the initial schema.

JanusGraph区分了两种类型的图索引:复合索引和混合索引。复合索引非常快速高效,但仅限于对特定的、先前定义的属性键组合进行相等查找。混合索引可用于查找索引键的任何组合,并支持多个条件谓词,此外,还可以根据备份索引存储进行相等。 这两种类型的索引都是通过JanusGraph管理系统和JanusGraphManagement.buildIndex(字符串,类)其中第一个参数定义索引的名称,第二个参数指定要索引的元素的类型(例如。顶点.class). 图索引的名称必须唯一。根据新定义的属性键(即在与索引相同的管理事务中定义的属性键)构建的图形索引将立即可用。这同样适用于约束到与索引在同一管理事务中创建的标签的图形索引。根据已在使用的属性键构建的图形索引不受新创建的标签的约束,需要执行重新编制索引过程,以确保索引包含以前添加的所有元素。在重新索引过程完成之前,索引将不可用。鼓励在与初始模式相同的事务中定义图索引。

Note

In the absence of an index, JanusGraph will default to a full graph scan in order to retrieve the desired list of vertices. While this produces the correct result set, the graph scan can be very inefficient and lead to poor overall system performance in a production environment. Enable the force-index configuration option in production deployments of JanusGraph to prohibit graph scans.

注:如果没有索引,JanuGraph将默认为完整的图扫描,以便检索所需的顶点列表。虽然这会产生正确的结果集,但图形扫描效率很低,并且会导致生产环境中系统整体性能较差。在JanuGraph的生产部署中启用force index configuration选项以禁止图形扫描。

Composite Index

Composite indexes retrieve vertices or edges by one or a (fixed) composition of multiple keys. Consider the following composite index definitions.

复合索引通过多个关键点的一个或一个(固定的)组合检索顶点或边。考虑下面的复合索引定义。

graph.tx().rollback() //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('byNameComposite', Vertex.class).addKey(name).buildCompositeIndex()
mgmt.buildIndex('byNameAndAgeComposite', Vertex.class).addKey(name).addKey(age).buildCompositeIndex()
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameComposite').call()
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameAndAgeComposite').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byNameAndAgeComposite"), SchemaAction.REINDEX).get()
mgmt.commit()

First, two property keys name and age are already defined. Next, a simple composite index on just the name property key is built. JanusGraph will use this index to answer the following query.

首先,已经定义了两个属性键name和age。接下来,只在name属性键上构建一个简单的复合索引。JanusGraph将使用此索引来回答以下查询。

g.V().has('name', 'hercules')

 

The second composite graph index includes both keys. JanusGraph will use this index to answer the following query.

第二个复合图索引包括两个键。JanusGraph将使用此索引来回答以下查询。

g.V().has('age', 30).has('name', 'hercules')

Note, that all keys of a composite graph index must be found in the query’s equality conditions for this index to be used. For example, the following query cannot be answered with either of the indexes because it only contains a constraint on age but not name.

注意,组合图索引的所有键必须在查询的相等条件中找到,才能使用此索引。例如,以下查询不能用任何一个索引来回答,因为它只包含年龄限制,而不包含名称限制。

g.V().has('age', 30)

 

Also note, that composite graph indexes can only be used for equality constraints like those in the queries above. The following query would be answered with just the simple composite index defined on the name key because the age constraint is not an equality constraint.

还要注意,复合图索引只能用于上面查询中的等式约束。下面的查询将只使用在name键上定义的简单复合索引来回答,因为age约束不是等式约束。

g.V().has('name', 'hercules').has('age', inside(20, 50))

 

Composite indexes do not require configuration of an external indexing backend and are supported through the primary storage backend. Hence, composite index modifications are persisted through the same transaction as graph modifications which means that those changes are atomic and/or consistent if the underlying storage backend supports atomicity and/or consistency.

复合索引不需要配置外部索引后端,而是通过主存储后端支持。因此,复合索引修改通过与图形修改相同的事务持久化,这意味着如果底层存储后端支持原子性和/或一致性,那么这些更改是原子性的和/或一致性的。

Note

A composite index may comprise just one or multiple keys. A composite index with just one key is sometimes referred to as a key-index.

注意:一个复合索引可以只包含一个或多个键。只有一个键的复合索引有时称为键索引。

Index Uniqueness

Composite indexes can also be used to enforce property uniqueness in the graph. If a composite graph index is defined as unique() there can be at most one vertex or edge for any given concatenation of property values associated with the keys of that index. For instance, to enforce that names are unique across the entire graph the following composite graph index would be defined.

索引唯一性

复合索引还可用于在图中强制属性唯一性。如果将复合图索引定义为unique(),则与该索引键关联的任何给定属性值串联最多只能有一个顶点或边。例如,为了强制名称在整个图中是唯一的,将定义以下复合图索引。

graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
mgmt.buildIndex('byNameUnique', Vertex.class).addKey(name).unique().buildCompositeIndex()
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameUnique').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameUnique"), SchemaAction.REINDEX).get()
mgmt.commit()

Note

To enforce uniqueness against an eventually consistent storage backend, the consistency of the index must be explicitly set to enabling locking.

注意:要对最终一致的存储后端强制执行唯一性,索引的一致性必须显式设置为启用锁定。

Mixed Index

Mixed indexes retrieve vertices or edges by any combination of previously added property keys. Mixed indexes provide more flexibility than composite indexes and support additional condition predicates beyond equality. On the other hand, mixed indexes are slower for most equality queries than composite indexes.

Unlike composite indexes, mixed indexes require the configuration of an indexing backend and use that indexing backend to execute lookup operations. JanusGraph can support multiple indexing backends in a single installation. Each indexing backend must be uniquely identified by name in the JanusGraph configuration which is called the indexing backend name.

混合索引通过先前添加的属性键的任何组合来检索顶点或边。混合索引提供了比复合索引更大的灵活性,并支持超过相等的附加条件谓词。另一方面,对于大多数等式查询来说,混合索引比复合索引慢。

与复合索引不同,混合索引需要配置索引后端并使用该索引后端来执行查找操作。JanusGraph可以在一个安装中支持多个索引后端。每个索引后端必须在JanusGraph配置中通过名称唯一标识,该配置称为indexing backend name

graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('nameAndAge', Vertex.class).addKey(name).addKey(age).buildMixedIndex("search")
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'nameAndAge').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("nameAndAge"), SchemaAction.REINDEX).get()
mgmt.commit()

 

The example above defines a mixed index containing the property keys name and age. The definition refers to the indexing backend name search so that JanusGraph knows which configured indexing backend it should use for this particular index. The search parameter specified in the buildMixedIndex call must match the second clause in the JanusGraph configuration definition like this: index.search.backend If the index was named solrsearch then the configuration definition would appear like this: index.solrsearch.backend.

The mgmt.buildIndex example specified above uses text search as its default behavior. An index statement that explicitly defines the index as a text index can be written as follows:

上面的示例定义了一个包含属性键“name”和“age”的混合索引。该定义引用了索引后端名称“search”,以便JanusGraph知道应该为该特定索引使用哪个配置的索引后端。buildMixedIndex调用中指定的“search”参数必须与JanusGraph配置定义中的第二个子句匹配,如下所示: index.search.backend如果索引名为solrsearch,则配置定义将显示为:index.solrsearch.backend。 这个mgmt.buildIndex示例使用文本搜索作为其默认行为。显式地将索引定义为文本索引的index语句可以编写如下:

mgmt.buildIndex('nameAndAge',Vertex.class).addKey(name,Mapping.TEXT.getParameter()).addKey(age,Mapping.TEXT.getParameter()).buildMixedIndex("search")

Label Constraint

In many cases it is desirable to only index vertices or edges with a particular label. For instance, one may want to index only gods by their name and not every single vertex that has a name property. When defining an index it is possible to restrict the index to a particular vertex or edge label using the indexOnly method of the index builder. The following creates a composite index for the property key name that indexes only vertices labeled god.

标签约束 在许多情况下,只需索引具有特定标签的顶点或边是可取的。例如,一个人可能只想索引神的名字,而不是每一个有名字属性的顶点。定义索引时,可以使用索引生成器的indexOnly方法将索引限制为特定顶点或边缘标签。下面为属性键名称创建一个复合索引,该索引只索引标记为god的顶点。

graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
god = mgmt.getVertexLabel('god')
mgmt.buildIndex('byNameAndLabel', Vertex.class).addKey(name).indexOnly(god).buildCompositeIndex()
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameAndLabel').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameAndLabel"), SchemaAction.REINDEX).get()
mgmt.commit()

Label restrictions similarly apply to mixed indexes. When a composite index with label restriction is defined as unique, the uniqueness constraint only applies to properties on vertices or edges for the specified label.

标签限制同样适用于混合索引。当具有标签限制的复合索引定义为唯一时,唯一性约束仅适用于指定标签的顶点或边上的属性。

Composite versus Mixed Indexes

  1. Use a composite index for exact match index retrievals. Composite indexes do not require configuring or operating an external index system and are often significantly faster than mixed indexes.

    1. As an exception, use a mixed index for exact matches when the number of distinct values for query constraint is relatively small or if one value is expected to be associated with many elements in the graph (i.e. in case of low selectivity).

  2. Use a mixed indexes for numeric range, full-text or geo-spatial indexing. Also, using a mixed index can speed up the order().by() queries.

使用复合索引进行精确的匹配索引检索。复合索引不需要配置或操作外部索引系统,而且通常比混合索引快得多。 作为一个例外,当查询约束的不同值的数目相对较少或一个值预期与图中的许多元素相关联时(即在低选择性的情况下),使用混合索引进行精确匹配。 对数字范围、全文或地理空间索引使用混合索引。另外,使用混合索引可以加快order().by()查询的速度。

Vertex-centric Indexes

Vertex-centric indexes are local index structures built individually per vertex. In large graphs vertices can have thousands of incident edges. Traversing through those vertices can be very slow because a large subset of the incident edges has to be retrieved and then filtered in memory to match the conditions of the traversal. Vertex-centric indexes can speed up such traversals by using localized index structures to retrieve only those edges that need to be traversed.

Suppose that Hercules battled hundreds of monsters in addition to the three captured in the introductory Graph of the Gods. Without a vertex-centric index, a query asking for those monsters battled between time point 10 and 20 would require retrieving all battled edges even though there are only a handful of matching edges.

顶点中心索引 以顶点为中心的索引是每个顶点单独构建的局部索引结构。在大型图中,顶点可以有数千条关联边。遍历这些顶点可能非常慢,因为必须检索大量的入射边子集,然后在内存中进行过滤,以匹配遍历的条件。以顶点为中心的索引可以通过使用本地化索引结构来只检索需要遍历的那些边来加快这种遍历。 假设大力神除了在神的介绍图中捕捉到的三个怪物外,还与数百个怪物作战。如果没有以顶点为中心的索引,查询那些在时间点10和20之间战斗的怪物将需要检索所有的战斗边缘,即使只有少数匹配的边缘。

h = g.V().has('name', 'hercules').next()
g.V(h).outE('battled').has('time', inside(10, 20)).inV()

 

Building a vertex-centric index by time speeds up such traversal queries. Note, this initial index example already exists in the Graph of the Gods as an index named edges. As a result, running the steps below will result in a uniqueness constraint error.

按时间构建以顶点为中心的索引可以加快这种遍历查询的速度。注意,这个初始索引示例已经作为一个名为edges的索引存在于神的图形中。因此,运行以下步骤将导致唯一性约束错误。

graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
time = mgmt.getPropertyKey('time')
battled = mgmt.getEdgeLabel('battled')
mgmt.buildEdgeIndex(battled, 'battlesByTime', Direction.BOTH, Order.desc, time)
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitRelationIndexStatus(graph, 'battlesByTime').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getRelationIndex(battled, "battlesByTime"), SchemaAction.REINDEX).get()
mgmt.commit()

This example builds a vertex-centric index which indexes battled edges in both direction by time in descending order. A vertex-centric index is built against a particular edge label which is the first argument to the index construction method JanusGraphManagement.buildEdgeIndex(). The index only applies to edges of this label - battled in the example above. The second argument is a unique name for the index. The third argument is the edge direction in which the index is built. The index will only apply to traversals along edges in this direction. In this example, the vertex-centric index is built in both direction which means that time restricted traversals along battled edges can be served by this index in both the IN and OUT direction. JanusGraph will maintain a vertex-centric index on both the in- and out-vertex of battled edges. Alternatively, one could define the index to apply to the OUT direction only which would speed up traversals from Hercules to the monsters but not in the reverse direction. This would only require maintaining one index and hence half the index maintenance and storage cost. The last two arguments are the sort order of the index and a list of property keys to index by. The sort order is optional and defaults to ascending order (i.e. Order.ASC). The list of property keys must be non-empty and defines the keys by which to index the edges of the given label. A vertex-centric index can be defined with multiple keys.

这个例子构建了一个以顶点为中心的索引,该索引按时间降序在两个方向上索引战斗边。以顶点为中心的索引是针对特定的边标签构建的,该标签是索引构造方法的第一个参数JanusGraphManagement.buildEdgeIndex(). 索引只适用于这个标签的边缘-在上面的例子中。第二个参数是索引的唯一名称。第三个参数是构建索引的边缘方向。索引只适用于沿此方向的边的遍历。在这个例子中,顶点中心索引是在两个方向上建立的,这意味着沿着战斗边缘的时间限制的遍历可以由这个索引在输入和输出方向上提供服务。JanusGraph将在战斗边缘的内外顶点上保持一个顶点中心索引。或者,你可以定义一个只适用于向外方向的索引,这样可以加快从大力神到怪物的穿越速度,但不能在相反的方向上。因此,维护索引只需要一半的存储成本。最后两个参数是索引的排序顺序和要作为索引依据的属性键列表。排序顺序是可选的,默认为升序(即。订单.ASC). 属性键列表必须为非空,并定义用于索引给定标签边缘的键。顶点中心索引可以用多个键定义。

graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
time = mgmt.getPropertyKey('time')
rating = mgmt.makePropertyKey('rating').dataType(Double.class).make()
battled = mgmt.getEdgeLabel('battled')
mgmt.buildEdgeIndex(battled, 'battlesByRatingAndTime', Direction.OUT, Order.desc, rating, time)
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitRelationIndexStatus(graph, 'battlesByRatingAndTime', 'battled').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getRelationIndex(battled, 'battlesByRatingAndTime'), SchemaAction.REINDEX).get()
mgmt.commit()

This example extends the schema by a rating property on battled edges and builds a vertex-centric index which indexes battled edges in the out-going direction by rating and time in descending order. Note, that the order in which the property keys are specified is important because vertex-centric indexes are prefix indexes. This means, that battled edges are indexed by rating first and time second.

这个例子扩展了这个模式,通过一个rating属性对batteredges进行了扩展,并构建了一个以顶点为中心的索引,该索引通过rating和time(按降序排列)在外向的方向上索引被攻击的边。注意,属性键的指定顺序很重要,因为以顶点为中心的索引是前缀索引。这意味着,战斗边缘被索引第一和时间第二。

h = g.V().has('name', 'hercules').next()
g.V(h).outE('battled').property('rating', 5.0) //Add some rating properties
g.V(h).outE('battled').has('rating', gt(3.0)).inV()
g.V(h).outE('battled').has('rating', 5.0).has('time', inside(10, 50)).inV()
g.V(h).outE('battled').has('time', inside(10, 50)).inV()

Hence, the battlesByRatingAndTime index can speed up the first two but not the third query.

Multiple vertex-centric indexes can be built for the same edge label in order to support different constraint traversals. JanusGraph’s query optimizer attempts to pick the most efficient index for any given traversal. Vertex-centric indexes only support equality and range/interval constraints.

因此,battlesByRatingAndTime索引可以加速前两个查询,但不能加快第三个查询。 为了支持不同的约束遍历,可以为同一个边标签构建多个以顶点为中心的索引。JanusGraph的查询优化器尝试为任何给定的遍历选择最有效的索引。以顶点为中心的索引只支持相等和范围/间隔约束。

Note

The property keys used in a vertex-centric index must have an explicitly defined data type (i.e. not Object.class) which supports a native sort order. This means not only that they must implement Comparable but that their serializer must implement OrderPreservingSerializer. The types that are currently supported are Boolean, UUID, Byte, Float, Long, String, Integer, Date, Double, Character, and Short

注意 在以顶点为中心的索引中使用的属性键必须具有明确定义的数据类型(即不是对象.类)它支持本机排序顺序。这意味着它们不仅必须实现Comparable,而且它们的序列化程序必须实现OrderPreservingSerializer。当前支持的类型有Boolean、UUID、Byte、Float、Long、String、Integer、Date、Double、Character和Short

If the vertex-centric index is built against either an edge label or at least one property key that is defined in the same management transaction, the index will be immediately available for querying. If both the edge label and all of the indexed property keys have already been in use, building a vertex-centric index against it requires the execution of a reindex procedure to ensure that the index contains all previously added edges. Until the reindex procedure has completed, the index will not be available.

如果以顶点为中心的索引是根据在同一管理事务中定义的边缘标签或至少一个属性键而构建的,则该索引将立即可用于查询。如果边标签和所有索引属性键都已在使用中,则针对它构建以顶点为中心的索引需要执行重新编制索引过程,以确保索引包含以前添加的所有边。在重新索引过程完成之前,索引将不可用。

Note

JanusGraph automatically builds vertex-centric indexes per edge label and property key. That means, even with thousands of incident battled edges, queries like g.V(h).out('mother') or g.V(h).values('age') are efficiently answered by the local index.

注意

JanusGraph会根据边标签和属性键自动构建以顶点为中心的索引。这意味着,即使有成千上万的事件边缘,像g.V(h).out('mother') or g.V(h).values('age')之类的查询都可以由本地索引有效地回答。

Vertex-centric indexes cannot speed up unconstrained traversals which require traversing through all incident edges of a particular label. Those traversals will become slower as the number of incident edges increases. Often, such traversals can be rewritten as constrained traversals that can utilize a vertex-centric index to ensure acceptable performance at scale.

以顶点为中心的索引不能加速无约束的遍历,这种遍历需要遍历特定标签的所有关联边。随着入射边数的增加,这些遍历将变慢。通常,这样的遍历可以重写为约束遍历,可以利用以顶点为中心的索引来确保可接受的缩放性能。

Ordered Traversals

The following queries specify an order in which the incident edges are to be traversed. Use the localLimit command to retrieve a subset of the edges (in a given order) for EACH vertex that is traversed.

有序遍历 下面的查询指定遍历事件边的顺序。使用localLimit命令为遍历的每个顶点检索边的子集(按给定的顺序)。

h = g..V().has('name', 'hercules').next()
g.V(h).local(outE('battled').order().by('time', desc).limit(10)).inV().values('name')
g.V(h).local(outE('battled').has('rating', 5.0).order().by('time', desc).limit(10)).values('place')

The first query asks for the names of the 10 most recently battled monsters by Hercules. The second query asks for the places of the 10 most recent battles of Hercules that are rated 5 stars. In both cases, the query is constrained by an order on a property key with a limit on the number of elements to be returned.

第一个查询询问大力神最近与之战斗的10个怪物的名字。第二个查询是最近10次大力神战役的位置,这些战役被评为5星。在这两种情况下,查询都受到属性键上的顺序的约束,并且对返回的元素数量有限制。

Such queries can also be efficiently answered by vertex-centric indexes if the order key matches the key of the index and the requested order (i.e. ascending or descending) is the same as the one defined for the index. The battlesByTime index would be used to answer the first query and battlesByRatingAndTime applies to the second. Note, that the battlesByRatingAndTime index cannot be used to answer the first query because an equality constraint on rating must be present for the second key in the index to be effective.

如果order键与索引键匹配,并且请求的顺序(即升序或降序)与为索引定义的顺序相同,则以顶点为中心的索引也可以有效地回答这些查询。battlesByTime索引将用于回答第一个查询,而battlesByRatingAndTime应用于第二个查询。请注意,battlesByRatingAndTime索引不能用于回答第一个查询,因为必须存在评级的相等约束,索引中的第二个键才能生效。

Index Lifecycle

JanusGraph uses only indexes which have status ENABLED. When the index is created it will not be used by JanusGraph until it is enabled. After the index is build you should wait until it is registered (i.e. available) by JanusGraph:

JanusGraph只使用启用了状态的索引。创建索引后,JanusGraph将不会使用它,直到启用它。构建索引后,您应该等到JanusGraph注册(即可用)之前:

//Wait for the index to become available (i.e. wait for status REGISTERED)
ManagementSystem.awaitGraphIndexStatus(graph, "myIndex").call();

After the index is registered we should either enable the index (if we are sure that the current data should not be indexed by the newly created index) or we should reindex current data so that it would be available in the newly created index.

Reindex the existing data and automatically enable the index example:

注册索引后,我们应该启用索引(如果我们确定当前数据不应该被新创建的索引索引),或者我们应该重新索引当前数据,以便它可以在新创建的索引中使用。 重新编制现有数据的索引并自动启用索引示例:

mgmt = graph.openManagement();
mgmt.updateIndex(mgmt.getGraphIndex("myIndex"), SchemaAction.REINDEX).get();
mgmt.commit();

Enable the index without reindexing existing data example:

启用索引而不重新索引现有数据示例:

mgmt = graph.openManagement();
mgmt.updateIndex(mgmt.getGraphIndex("myAnotherIndex"), SchemaAction.ENABLE_INDEX).get();
mgmt.commit();

Index states and transitions

 

States (SchemaStatus)

An index can be in one of the following states:

  • INSTALLED The index is installed in the system but not yet registered with all instances in the cluster

  • REGISTERED The index is registered with all instances in the cluster but not (yet) enabled

  • ENABLED The index is enabled and in use

  • DISABLED The index is disabled and no longer in use

Actions (SchemaAction)

The following actions can be performed on an index to change its state via mgmt.updateIndex():

  • REGISTER_INDEX Registers the index with all instances in the graph cluster. After an index is installed, it must be registered with all graph instances

  • REINDEX Re-builds the index from the graph

  • ENABLE_INDEX Enables the index so that it can be used by the query processing engine. An index must be registered before it can be enabled.

  • DISABLE_INDEX Disables the index in the graph so that it is no longer used.

  • REMOVE_INDEX Removes the index from the graph (optional operation). Only on composite index.

注册并启用索引需要用到的命令(注:执行前需关闭其他只用于读的gremlin-server实例):

graph = JanusGraphFactory.open("conf/gremlin-server/socket-janusgraph-hbase-solr.properties")
g = graph.traversal()
graph.tx().rollback()
graph.getOpenTransactions()
graph.tx().rollback()
mgmt = graph.openManagement()
graph.getOpenTransactions()
uid = mgmt.getPropertyKey('uid')
app = mgmt.getPropertyKey('appName')
host = mgmt.getPropertyKey('hostName')
mgmt.buildIndex('byUidComposite', Vertex.class).addKey(uid).buildCompositeIndex()
mgmt.buildIndex('byAppComposite', Vertex.class).addKey(app).buildCompositeIndex()
mgmt.buildIndex('byHostComposite', Vertex.class).addKey(host).buildCompositeIndex()
mgmt.commit()
graph.getOpenTransactions()
ManagementSystem.awaitGraphIndexStatus(graph, 'byUidComposite').call()
ManagementSystem.awaitGraphIndexStatus(graph, 'byAppComposite').call()
ManagementSystem.awaitGraphIndexStatus(graph, 'byHostComposite').call()
mgmt = graph.openManagement()
graph.getOpenTransactions()
mgmt.updateIndex(mgmt.getGraphIndex("byUidComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byAppComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byHostComposite"), SchemaAction.REINDEX).get()
mgmt.commit()

查看索引的状态:

mgmt = graph.openManagement()
uidIndex = mgmt.getGraphIndex('byUidComposite')
uidIndex.getIndexStatus(mgmt.getPropertyKey('uid'))
appIndex = mgmt.getGraphIndex('byAppComposite')
appIndex.getIndexStatus(mgmt.getPropertyKey('appName'))
hostIndex = mgmt.getGraphIndex('byHostComposite')
hostIndex.getIndexStatus(mgmt.getPropertyKey('hostName'))
mgmt.commit()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值