Neo4j中的Cypher查询返回“undefined”

4

我使用Neo4j构建了一个图,其中包含约1000个节点和约270,000个关系。该图是一个航班网络(机场是节点,航班是关系),因此从节点到节点有许多关系。我确定在某些查询中也有许多循环(我不确定这是否是问题)。无论如何,某些查询可以正常工作,例如:

start a=node(1), b=node(2) match p=a-[:flys_to*..1]->b return p;
start a=node(1), b=node(2) match p=shortestPath(a-[:flys_to]->b) return p;

但当我尝试其他更复杂的查询时,没有友好的错误消息; 它只是挂起大约3分钟(取决于我搜索的两个节点)并返回“未定义”。

其中一个挂起的查询看起来像这样:

start a=node(1), b=node(2) match p=a-[:flys_to*..2]->b return p;

此外,有趣的是当我输入以下查询时,它立即返回“未定义”:
start a=node(1), b=node(2) match p=a-[:flys_to]->b return p;

这是否有意义,或者是否有任何想法可以指导我开始排除故障?

关于此特定问题的更多信息

这是数据库的压缩文件:http://www.opensourcebanking.org/neo4j/

我在虚拟环境中运行此程序,使用的是 VMware。主机是 OSX 10.8.2,客户端是 Windows Server 2012。JRE 版本为 1.6.0_38。此外,我已经在节点属性“iata”和关系属性“flys_to”上设置了自动索引。

以下是一些 Cypher 查询及其相关的日志消息:

以下查询几乎立即返回“未定义”:

start a=node(353), b=node(295)
match p=a-->b
return p;

以下是日志中的内容:

SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
org.neo4j.helpers.ThisShouldNotHappenError: Developer: Andres claims that: Unexpected traversal state encountered
    at org.neo4j.cypher.internal.pipes.matching.BidirectionalTraversalMatcher$StepCollisionDetector.includePath(BidirectionalTraversalMatcher.scala:101)
    at org.neo4j.kernel.StandardBranchCollisionDetector.evaluate(StandardBranchCollisionDetector.java:74)
    at org.neo4j.kernel.StandardBranchCollisionDetector.evaluate(StandardBranchCollisionDetector.java:37)
    at org.neo4j.kernel.impl.traversal.BidirectionalTraverserIterator.fetchNextOrNull(BidirectionalTraverserIterator.java:157)
    at org.neo4j.kernel.impl.traversal.BidirectionalTraverserIterator.fetchNextOrNull(BidirectionalTraverserIterator.java:41)
    at org.neo4j.helpers.collection.PrefetchingIterator.hasNext(PrefetchingIterator.java:55)
    at scala.collection.JavaConversions$JIteratorWrapper.hasNext(JavaConversions.scala:574)
    at scala.collection.Iterator$$anon$21.hasNext(Iterator.scala:371)
    at scala.collection.Iterator$$anon$21.hasNext(Iterator.scala:371)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:36)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:35)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:35)
    at org.neo4j.cypher.internal.ClosingIterator.failIfThrows(ClosingIterator.scala:87)
    at org.neo4j.cypher.internal.ClosingIterator.hasNext(ClosingIterator.scala:35)
    at scala.collection.Iterator$class.foreach(Iterator.scala:660)
    at org.neo4j.cypher.internal.ClosingIterator.foreach(ClosingIterator.scala:31)
    at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
    at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:128)
    at scala.collection.TraversableOnce$class.toList(TraversableOnce.scala:242)
    at org.neo4j.cypher.internal.ClosingIterator.toList(ClosingIterator.scala:31)
    at org.neo4j.cypher.PipeExecutionResult.createTimedResults(PipeExecutionResult.scala:73)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:80)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:125)
    at org.neo4j.cypher.javacompat.ExecutionResult.dumpToString(ExecutionResult.java:91)
    at org.neo4j.shell.kernel.apps.Start.exec(Start.java:71)
    at org.neo4j.shell.kernel.apps.ReadOnlyGraphDatabaseApp.execute(ReadOnlyGraphDatabaseApp.java:32)
    at org.neo4j.shell.impl.AbstractAppServer.interpretLine(AbstractAppServer.java:115)
    at org.neo4j.shell.kernel.GraphDatabaseShellServer.interpretLine(GraphDatabaseShellServer.java:92)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:130)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:114)
    at org.neo4j.server.webadmin.console.ShellSession.evaluate(ShellSession.java:101)
    at org.neo4j.server.webadmin.rest.console.ConsoleService.exec(ConsoleService.java:125)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

以下查询正常运行。它返回了426行数据,没有任何日志记录。
start a=node(353), b=node(295)
match p=a-[:flys_to*..1]->b
return p;

以下查询在大约10-15分钟后返回“undefined”:
start a=node(353), b=node(295)
match p=a-[:flys_to*..2]->b
return p;

日志:

SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
java.lang.OutOfMemoryError: Java heap space
    at org.neo4j.cypher.internal.pipes.matching.AddedHistory.toSeq(History.scala:87)
    at org.neo4j.cypher.internal.pipes.matching.AddedHistory.toMap(History.scala:75)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.isMatchSoFar(PatternMatcher.scala:166)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.org$neo4j$cypher$internal$pipes$matching$PatternMatcher$$traverseNextNodeFromRelationship(PatternMatcher.scala:98)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher$$anonfun$4.apply(PatternMatcher.scala:150)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher$$anonfun$4.apply(PatternMatcher.scala:150)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:175)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:175)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:634)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:626)
    at scala.collection.immutable.Stream.foldLeft(Stream.scala:302)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.traverseRelationship(PatternMatcher.scala:150)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.traverseNextSpecificNode(PatternMatcher.scala:61)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.traverseNode(PatternMatcher.scala:72)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.foreach(PatternMatcher.scala:36)
    at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
    at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:99)
    at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:250)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.toBuffer(PatternMatcher.scala:28)
    at scala.collection.TraversableLike$class.toStream(TraversableLike.scala:571)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.toStream(PatternMatcher.scala:28)
    at scala.collection.TraversableLike$class.toIterator(TraversableLike.scala:570)
    at org.neo4j.cypher.internal.pipes.matching.PatternMatcher.toIterator(PatternMatcher.scala:28)
    at scala.collection.Iterator$$anon$21.hasNext(Iterator.scala:371)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:36)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:35)
    at org.neo4j.cypher.internal.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:35)
    at org.neo4j.cypher.internal.ClosingIterator.failIfThrows(ClosingIterator.scala:87)
    at org.neo4j.cypher.internal.ClosingIterator.hasNext(ClosingIterator.scala:35)

你应该在console.neo4j.org上提供一个样例数据库,让我们可以进行操作。 - Werner Kvalem Vesterås
@ulkas 感谢您的回复。我今天早些时候尝试在1.8.1和1.9.M03上重新创建图表,但遗憾的是,我仍然遇到了同样的问题。 - Brent Barbata
@MichaelHunger,没问题,我可以分享一份压缩的数据库副本。这里是链接。我还更新了原始问题,并附上了一些查询及其相关的日志消息(如果有)。我之前使用2GB RAM运行这台机器,但在你问我之后,我将其升级到了8GB。有趣的是,在增加内存后,它不再在大约3分钟后挂起并返回“未定义”,而是现在挂起大约10-15分钟并返回“未定义”。 (日志还显示内存不足。) - Brent Barbata
我认为这里的问题是由于节点之间有太多的关系,导致出现了许多"循环"。所谓的循环,是指虽然从一个节点到另一个节点的路径/关系不同,但在路径中出现了相同的节点。以下是带有控制台的示例:http://console.neo4j.org/?id=k34uet。是否有一种方法可以在遇到两个相同的节点时终止路径?我看过使用“WITH ALL...”的示例,但我担心它无法解决内存不足的问题,因为MATCH在WITH之前运行。这样正确吗? - Brent Barbata
实际上,匹配尝试尽可能地拉取多个表达式以减少匹配。 - Michael Hunger
显示剩余3条评论
2个回答

0

对我来说,这将返回 426 行:

start a=node(353), b=node(295)
match p=a-->b
return p;

这真是太奇怪了。每次我尝试运行这个查询,都会出现我上面发布的错误。你认为这可能与我正在运行它的环境有关吗(Win 2012 Svr和Java 6)? - Brent Barbata
所以我已经升级到Neo4j M04和Java 7u17,现在这个查询似乎工作正常了。它现在返回426行。但是对于那些通过同一节点多次路由的更大的查询,我仍然遇到内存不足的问题。我将尝试添加更多属性到关系中(如航班日期和时间),以减少可能路径的数量。我们会看看它是否奏效。 - Brent Barbata

0
你尝试过在查询中使用shortestPathallShortestPaths吗?
 start a=node(1), b=node(2) match p=allShortestPaths(a-[:flys_to*..2]->b) return p;


+--------------------------------------------------------------------------------------------------------+
| p                                                                                                      |
+--------------------------------------------------------------------------------------------------------+
| [Node[1]{iata:"ABE"},:flys_to[224044] {},Node[546]{iata:"SFO"},:flys_to[24211] {},Node[2]{iata:"ABI"}] |
| [Node[1]{iata:"ABE"},:flys_to[224044] {},Node[546]{iata:"SFO"},:flys_to[24210] {},Node[2]{iata:"ABI"}] |
....
| [Node[1]{iata:"ABE"},:flys_to[66032] {},Node[146]{iata:"DFW"},:flys_to[1] {},Node[2]{iata:"ABI"}]      |
| [Node[1]{iata:"ABE"},:flys_to[66032] {},Node[146]{iata:"DFW"},:flys_to[0] {},Node[2]{iata:"ABI"}]      |
+--------------------------------------------------------------------------------------------------------+
28 rows
20 ms
 start a=node(1), b=node(2) match p=shortestPath(a-[:flys_to*..2]->b) return p;

+--------------------------------------------------------------------------------------------------------+
| p                                                                                                      |
+--------------------------------------------------------------------------------------------------------+
| [Node[1]{iata:"ABE"},:flys_to[224044] {},Node[546]{iata:"SFO"},:flys_to[24211] {},Node[2]{iata:"ABI"}] |
+--------------------------------------------------------------------------------------------------------+
1 row
1 ms

是的,我确实尝试过那些(它们总是非常快),但我希望能够设置最大跳数,然后获取该限制下的所有路径。例如,如果设置为最多2个跳,我希望它返回所有1个跳和2个跳的路径。 - Brent Barbata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接