I've written a JUnit Test to check against the generate-modern.groovy graph if marko exists.
My gremlin query being
"g.V().has('name','marko')";
As you can see in the generate-modern.groovy file that indexing is already applied on the name property of the person.
I later made the following
query.force-index=true
property true in the dynamodb.properties file which blocks whole graph scan thereby making indexing mandatory.
However it throws me the following exception
org.janusgraph.core.JanusGraphException: Could not find a suitable index to answer graph query and graph scans are disabled: [(name = marko)]:VERTEX
The above exception is raised from the following StandardJanusGraphTx class's method
@Override
public Iterator<JanusGraphElement> execute(final GraphCentricQuery query, final JointIndexQuery indexQuery, final Object exeInfo, final QueryProfiler profiler) {
Iterator<JanusGraphElement> iter;
if (!indexQuery.isEmpty()) {
List<QueryUtil.IndexCall<Object>> retrievals = new ArrayList<QueryUtil.IndexCall<Object>>();
for (int i = 0; i < indexQuery.size(); i++) {
final JointIndexQuery.Subquery subquery = indexQuery.getQuery(i);
retrievals.add(new QueryUtil.IndexCall<Object>() {
@Override
public Collection<Object> call(int limit) {
final JointIndexQuery.Subquery adjustedQuery = subquery.updateLimit(limit);
try {
return indexCache.get(adjustedQuery, new Callable<List<Object>>() {
@Override
public List<Object> call() throws Exception {
return QueryProfiler.profile(subquery.getProfiler(), adjustedQuery, q -> indexSerializer.query(q, txHandle));
}
});
} catch (Exception e) {
throw new JanusGraphException("Could not call index", e.getCause());
}
}
});
}
List<Object> resultSet = QueryUtil.processIntersectingRetrievals(retrievals, indexQuery.getLimit());
iter = com.google.common.collect.Iterators.transform(resultSet.iterator(), getConversionFunction(query.getResultType()));
} else {
if (config.hasForceIndexUsage()) throw new JanusGraphException("Could not find a suitable index to answer graph query and graph scans are disabled: " + query);
log.warn("Query requires iterating over all vertices [{}]. For better performance, use indexes", query.getCondition());
QueryProfiler sub = profiler.addNested("scan");
sub.setAnnotation(QueryProfiler.QUERY_ANNOTATION,indexQuery);
sub.setAnnotation(QueryProfiler.FULLSCAN_ANNOTATION,true);
sub.setAnnotation(QueryProfiler.CONDITION_ANNOTATION,query.getResultType());
switch (query.getResultType()) {
case VERTEX:
return (Iterator) getVertices().iterator();
case EDGE:
return (Iterator) getEdges().iterator();
case PROPERTY:
return new VertexCentricEdgeIterable(getInternalVertices(),RelationCategory.PROPERTY).iterator();
default:
throw new IllegalArgumentException("Unexpected type: " + query.getResultType());
}
}
return iter;
}
};
As you can observe from the method that the exception is raised when the JointIndexQuery object is empty(arrayList being empty) and force index is true.
The problem is why the list is empty? when we have specified the indexing query against the name property in the generate-modern.groovy while querying from a JUnit Test.This works fine meaning the list is not empty when the same data is being preloaded into the gremlin server with the same file.
The personByName
index definition uses a label constraint.
def personByName = mgmt.buildIndex("personByName", Vertex.class).addKey(name).indexOnly(person).buildCompositeIndex()
In order to take advantage of that index, you must use the label and the property. For example:
g.V().has('person', 'name', 'marko')
You can read more about this in the JanusGraph documentation http://docs.janusgraph.org/latest/indexes.html#_label_constraint