【问题标题】:Indexing fails on enabling force index in Titan/Janus在 Titan/Janus 中启用力索引时索引失败
【发布时间】:2018-01-04 11:00:43
【问题描述】:

我编写了一个 JUnit 测试来检查 generate-modern.groovy 图表是否存在 marko。
我的 gremlin 查询是

"g.V().has('name','marko')";

正如您在generate-modern.groovy 文件中看到的那样,索引已应用于人员的名称属性。 我后来做了以下

query.force-index=true

dynamodb.properties 文件中的属性为 true,它阻止整个图形扫描,从而强制索引。 但是它抛出了以下异常

org.janusgraph.core.JanusGraphException: Could not find a suitable index to answer graph query and graph scans are disabled: [(name = marko)]:VERTEX

上述异常是从以下 StandardJanusGraphTx 类的方法引发的

    @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;
    }

};

从方法中可以看出,当 JointIndexQuery 对象为空(arrayList 为空)且强制索引为 true 时引发异常。
问题是为什么列表是空的?当我们在从 JUnit 测试中查询时在 generate-modern.groovy 中指定了针对名称属性的索引查询时。这工作正常意味着当相同的数据被预加载到具有相同文件的 gremlin 服务器中时列表不为空。

【问题讨论】:

  • 您能否提供整个失败的 JUnit 测试?这里可能会发生很多事情。如果您只是使用generate-modern.groovy 脚本并尝试在服务器启动之外加载它,那么您将遇到问题,因为它被设置为在服务器生命周期中作为挂钩运行并且实际上不会生成任何东西。如果不是这种情况,如果您在测试中使用的图表上创建了任何顶点标签,脚本将不会创建索引。
  • 不,我在创建 server 时加载脚本。我已经验证了这一事实,因为当我将 force index 属性切换为 false 时,我的测试用例成功通过。
  • force-index 设置为false 后的成功向我表明,当时没有创建简单的索引。您是否已经在尝试将其加载到图表中的数据? github.com/pluradj/titan-tp3-driver-example/blob/master/scripts/… 假设您使用的是没有预先存在的顶点标签的空图。
  • 是的,图表已正确加载。我在调试模式下运行代码,发现它从未进入 StandardJanusGraphTx 类方法的 else 部分。这证明正在创建索引
  • 使用管理类获取索引状态的结果是什么?

标签: titan tinkerpop3 janusgraph


【解决方案1】:

personByNameindex definition 使用标签约束。

def personByName = mgmt.buildIndex("personByName", Vertex.class).addKey(name).indexOnly(person).buildCompositeIndex()

为了利用该索引,您必须使用标签和属性。例如:

g.V().has('person', 'name', 'marko')

您可以在 JanusGraph 文档http://docs.janusgraph.org/latest/indexes.html#_label_constraint中阅读更多相关信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 2017-09-21
    • 2017-03-27
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多