【问题标题】:cypher query BadInputException密码查询 BadInputException
【发布时间】:2015-03-12 15:52:20
【问题描述】:

在我的图中,大约有 196 000 个 C 节点、600 000 个 A 节点和 800 000 个 S 节点。 99% 的 C 连接到单个 A(每个 A 有 0 - 20 个相关的 C),并且所有 A 都连接到单个 S。

我正在运行以下查询

MATCH (c:C)<-[d:D]-(:A)<-[:u]-(s:S) 
WITH s, d, c, 
    CASE WHEN c.start - 1 - 20000 < 0 
    THEN 0 
    ELSE c.start - 1 - 20000 END AS start 
RETURN s.r, c.type, d.index, 
       substring(s.se, start, c.end-start + 1 + 20000);

它运行了大约 2.5 小时,然后我得到了这个响应:

    {
  "message" : "The statement has been closed.",
  "exception" : "BadInputException",
  "fullname" : "org.neo4j.server.rest.repr.BadInputException",
  "stacktrace" : [ "org.neo4j.server.rest.repr.RepresentationExceptionHandlingIterable.exceptionOnHasNext(RepresentationExceptionHandlingIterable.java:50)", "org.neo4j.helpers.collection.ExceptionHandlingIterable$1.hasNext(ExceptionHandlingIterable.java:46)", "org.neo4j.helpers.collection.IteratorWrapper.hasNext(IteratorWrapper.java:42)", "org.neo4j.server.rest.repr.ListRepresentation.serialize(ListRepresentation.java:71)", "org.neo4j.server.rest.repr.Serializer.serialize(Serializer.java:75)", "org.neo4j.server.rest.repr.MappingSerializer.putList(MappingSerializer.java:61)", "org.neo4j.server.rest.repr.CypherResultRepresentation.serialize(CypherResultRepresentation.java:83)", "org.neo4j.server.rest.repr.MappingRepresentation.serialize(MappingRepresentation.java:41)", "org.neo4j.server.rest.repr.OutputFormat.assemble(OutputFormat.java:215)", "org.neo4j.server.rest.repr.OutputFormat.formatRepresentation(OutputFormat.java:147)", "org.neo4j.server.rest.repr.OutputFormat.response(OutputFormat.java:130)", "org.neo4j.server.rest.repr.OutputFormat.ok(OutputFormat.java:67)", "org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:101)", "java.lang.reflect.Method.invoke(Method.java:606)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)", "java.lang.Thread.run(Thread.java:745)" ],
  "cause" : {
    "message" : "The statement has been closed.",
    "exception" : "NotInTransactionException",

我只是通过 curl 运行这个查询,如下所示

curl -g -H Accept:application/json -H Content-Type:application/json -X POST  -d '{ "query":"MATCH (c:C)<-[d:D]-(:a)<-[:u]-(s:S) WITH s, d, c, CASE WHEN c.start - 1 - 20000 < 0 THEN 0 ELSE c.start - 1 - 20000 END AS start RETURN s.r, c.type, d.index, substring(s.se, start, c.end-start + 1 + 20000);", "params" : {} }'  localhost:7474/db/data/cypher -o data.json

我添加了“限制 3;”到查询,它确实运行并返回预期结果。

我没有正确优化查询吗?我已经阅读了有关查询优化的信息,但看不到任何可以改进的地方,尽管我敢打赌。我也找不到太多关于解决该异常的文档。

任何帮助都会很棒!谢谢

编辑:修正错字

编辑:我使用附加的“WHERE c.prop = 'x'”重新运行相同的查询以限制初始 C 匹配,然后它返回 OutOfMemory 异常。然后我做了更多阅读,并从迈克尔的帖子here 中发现了this。我的查询现在正在运行,我认为它正在运行。 (有很多数据,它正在将其下载到一个越来越大的文件中。)

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    所以你试图匹配很多不同的路径,我认为你可能做的计算比必要的多。您可能想尝试这种重新表述:

    MATCH (c:C)
    WITH c, CASE WHEN c.start - 20001 < 0
               THEN 0 ELSE c.start - 20001 as start
    MATCH (c)<-[d:D]-(:A)<-[:u]-(s:S)
    WITH c, start, s, d
    RETURN s.r, c.type, d.index, substring(s.se, start, c.end - start + 20001);
    

    我的想法是,在任何节点中,C 的数量最少。因此,从那里开始比赛,首先进行数学计算,然后以此为基础进行后续比赛。否则,您会根据有多少其他节点重新匹配c 很多次。您可以根据下一个最有选择性的A 和附加的with 子句进一步细分。我认为这会有所帮助。

    【讨论】:

      【解决方案2】:

      您使用的是哪个 Neo4j 版本?

      我认为您正在创建数十亿条路径。

      查看基数:

      (c:C*196k)<-[d:D*1..20]-(:A*600k)<-[:u*1..1]-(s:S*800k) 
      

      简述你的陈述,我认为让它从 C 开始,然后沿着单 a 和单 s 的路径从那里开始是有意义的。

      所以你可以使用USING SCAN c:C 强制 Cypher 通过索引扫描 C 节点,这应该会给你 196k 路径。

      这些 c 节点中的每一个都将沿着单节点路径匹配。

      所以尝试@FrobberOfBits 建议以及分析和限制第一个WITH 以查看是否返回了正确的数据。

      见:http://neo4j.com/docs/stable/query-using.html#using-hinting-a-label-scan

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多