diff --git a/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/OrientGraph.java b/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/OrientGraph.java index 97258c88..aa0ab6c4 100644 --- a/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/OrientGraph.java +++ b/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/OrientGraph.java @@ -179,20 +179,19 @@ protected Object convertKey(final OIndex idx, Object iValue) { return iValue; } - public Stream getIndexedVertices(OrientIndexQuery indexReference) { + // TODO: make value optional + public Stream getIndexedVertices(OIndex index, Object value) { makeActive(); // if (iKey.equals("@class")) // return getVerticesOfClass(iValue.toString()); - final OIndex idx = database.getMetadata().getIndexManager().getIndex(indexReference.indexName()); - Object iValue = indexReference.value; - if (idx == null) { + if (index == null) { // NO INDEX return Collections.emptyList().stream(); } else { - iValue = convertKey(idx, iValue); - Object indexValue = idx.get(iValue); + value = convertKey(index, value); + Object indexValue = index.get(value); if (indexValue == null) { return Collections.emptyList().stream(); } else if (!(indexValue instanceof Iterable)) { diff --git a/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/traversal/step/sideEffect/OrientGraphStep.java b/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/traversal/step/sideEffect/OrientGraphStep.java index 5853df4a..99f84422 100644 --- a/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/traversal/step/sideEffect/OrientGraphStep.java +++ b/driver/src/main/java/org/apache/tinkerpop/gremlin/orientdb/traversal/step/sideEffect/OrientGraphStep.java @@ -1,6 +1,9 @@ package org.apache.tinkerpop.gremlin.orientdb.traversal.step.sideEffect; import com.orientechnologies.common.log.OLogManager; +import com.orientechnologies.orient.core.index.OIndex; +import com.orientechnologies.orient.core.index.OIndexManagerProxy; +import com.orientechnologies.orient.core.metadata.schema.OImmutableClass; import org.apache.tinkerpop.gremlin.orientdb.OrientIndexQuery; import org.apache.tinkerpop.gremlin.orientdb.OrientGraph; import org.apache.tinkerpop.gremlin.orientdb.OrientVertex; @@ -35,20 +38,24 @@ private boolean isVertexStep() { private Iterator vertices() { final OrientGraph graph = (OrientGraph) this.getTraversal().getGraph().get(); - final Optional indexQuery = getIndexQuery(); if (this.ids != null && this.ids.length > 0) { return this.iteratorList(graph.vertices(this.ids)); - } else if (!indexQuery.isPresent()) { - OLogManager.instance().warn(this, "scanning through all vertices without using an index"); - return this.iteratorList(graph.vertices()); } else { - OLogManager.instance().info(this, "index will be queried with " + indexQuery.get()); - Stream indexedVertices = graph.getIndexedVertices(indexQuery.get()); - return indexedVertices - .filter(vertex -> HasContainer.testAll(vertex, this.hasContainers)) - .collect(Collectors.toList()) - .iterator(); + Optional> indexAndValue = findIndex(); + if (indexAndValue.isPresent()) { + OIndex index = indexAndValue.get().getValue0(); + Object value = indexAndValue.get().getValue1(); + OLogManager.instance().info(this, "index [" + indexAndValue.get() + "] will be used"); + Stream indexedVertices = graph.getIndexedVertices(index, value); + return indexedVertices + .filter(vertex -> HasContainer.testAll(vertex, this.hasContainers)) + .collect(Collectors.toList()) + .iterator(); + } else { + OLogManager.instance().warn(this, "scanning through all vertices without using an index"); + return this.iteratorList(graph.vertices()); + } } } @@ -82,9 +89,11 @@ private OrientGraph getGraph() { return ((OrientGraph) this.getTraversal().getGraph().get()); } - private Optional getIndexQuery() { - Optional elementLabel = findElementLabelInHasContainers(); - OrientGraph graph = getGraph(); + private Optional> findIndex() { + final Optional elementLabel = findElementLabelInHasContainers(); + final OrientGraph graph = getGraph(); + final OIndexManagerProxy indexManager = graph.database().getMetadata().getIndexManager(); + // find indexed keys only for the element subclass (if present) final Set indexedKeys = elementLabel.isPresent() ? graph.getIndexedKeys(this.returnClass, elementLabel.get()) : @@ -97,12 +106,23 @@ private Optional getIndexQuery() { .map(c -> Optional.of(new Pair<>(c.getKey(), c.getValue()))) .orElseGet(Optional::empty); - if (indexedKeyAndValue.isPresent()) { + if (elementLabel.isPresent() && indexedKeyAndValue.isPresent()) { String key = indexedKeyAndValue.get().getValue0(); Object value = indexedKeyAndValue.get().getValue1(); - return Optional.of(new OrientIndexQuery(isVertexStep(), elementLabel, key, value)); - } else - return Optional.empty(); + + String className = OImmutableClass.VERTEX_CLASS_NAME + '_' + elementLabel.get(); + Set> classIndexes = indexManager.getClassIndexes(className); + Iterator> keyIndexes = classIndexes.stream().filter(idx -> idx.getDefinition().getFields().contains(key)).iterator(); + + if (keyIndexes.hasNext()) { + // TODO: implement algorithm to select best index if there are multiple + return Optional.of(new Pair(keyIndexes.next(), value)); + } else { + OLogManager.instance().warn(this, "no index found for class=[" + className + "] and key=[" + key + "]"); + } + } + + return Optional.empty(); } @Override