我是neo4j和cypher的新手,我正在努力解决下面的问题。
我的存储库界面中有一个方法,在给定成员ID的情况下返回朋友列表的朋友。我的POJO是会员,其中包含会员类型的朋友列表。
@Query("MATCH path=(me:Member {id: '{id}'})-[f:FRIEND]->(friend:Member) WITH [x in nodes(path) | id(x) AS friends] WHERE id(me) in friends MATCH friends-[ff:FRIEND]->(fof:Member) return fof")
public Collection<Member> findByIdFriendsOfFriend(@Param("id") Long id);
我正在使用来自给定依赖项的neo4j版本:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
</dependency>
这是我得到的堆栈跟踪:
org.neo4j.rest.graphdb.RestResultException: Invalid input 'S': expected 'n/N' (line 1, column 97)
"MATCH path=(me:Member {id: '{id}'})-[f:FRIEND]->(friend:Member) WITH [x in nodes(path) | id(x) AS friends] WHERE id(me) in friends MATCH friends-[ff:FRIEND]->(fof:Member) return fof"
^ at
SyntaxException
org.neo4j.cypher.internal.compiler.v2_1.parser.CypherParser$$anonfun$parse$1.apply(CypherParser.scala:57)
org.neo4j.cypher.internal.compiler.v2_1.parser.CypherParser$$anonfun$parse$1.apply(CypherParser.scala:47)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
scala.collection.immutable.List.foreach(List.scala:318)
scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
scala.collection.AbstractTraversable.map(Traversable.scala:105)
org.neo4j.cypher.internal.compiler.v2_1.parser.CypherParser.parse(CypherParser.scala:46)
org.neo4j.cypher.internal.compiler.v2_1.CypherCompiler.prepareQuery(CypherCompiler.scala:107)
org.neo4j.cypher.internal.CypherCompiler$$anon$2$$anonfun$5.apply(CypherCompiler.scala:85)
org.neo4j.cypher.internal.CypherCompiler$$anon$2$$anonfun$5.apply(CypherCompiler.scala:85)
scala.util.Try$.apply(Try.scala:161)
org.neo4j.cypher.internal.CypherCompiler$$anon$2.<init>(CypherCompiler.scala:85)
org.neo4j.cypher.internal.CypherCompiler.parseQuery(CypherCompiler.scala:84)
org.neo4j.cypher.ExecutionEngine$$anonfun$parseQuery$1.apply(ExecutionEngine.scala:81)
org.neo4j.cypher.ExecutionEngine$$anonfun$parseQuery$1.apply(ExecutionEngine.scala:81)
org.neo4j.cypher.internal.LRUCache.getOrElseUpdate(LRUCache.scala:35)
org.neo4j.cypher.ExecutionEngine.parseQuery(ExecutionEngine.scala:81)
org.neo4j.cypher.internal.ServerExecutionEngine.isPeriodicCommit(ServerExecutionEngine.scala:34)
org.neo4j.cypher.javacompat.internal.ServerExecutionEngine.isPeriodicCommit(ServerExecutionEngine.java:56)
org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:99)
java.lang.reflect.Method.invoke(Method.java:483)
org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)
java.lang.Thread.run(Thread.java:745)
at org.neo4j.rest.graphdb.ExecutingRestAPI.query(ExecutingRestAPI.java:569)
at org.neo4j.rest.graphdb.RestAPIFacade.query(RestAPIFacade.java:235)
at org.neo4j.rest.graphdb.query.RestCypherQueryEngine.query(RestCypherQueryEngine.java:50)
at org.springframework.data.neo4j.rest.SpringRestCypherQueryEngine.query(SpringRestCypherQueryEngine.java:48)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.dispatchQuery(GraphRepositoryQuery.java:107)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery$1.doWithGraph(GraphRepositoryQuery.java:89)
at org.springframework.data.neo4j.support.Neo4jTemplate.doExecute(Neo4jTemplate.java:457)
at org.springframework.data.neo4j.support.Neo4jTemplate.access$000(Neo4jTemplate.java:87)
at org.springframework.data.neo4j.support.Neo4jTemplate$2.doInTransaction(Neo4jTemplate.java:471)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.data.neo4j.support.Neo4jTemplate.exec(Neo4jTemplate.java:468)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.execute(GraphRepositoryQuery.java:83)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:421)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:512)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy110.findByIdFriendsOfFriend(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201)
at com.sun.proxy.$Proxy115.findByIdFriendsOfFriend(Unknown Source)
at com.shop.test.repository.Neo4jRepositoryTest.testQuery(Neo4jRepositoryTest.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
我已将查询更新为:
@Query("MATCH (me:Member { id: '{id}' })-[:FRIEND*2..2]-(friend_of_friend:Member) WHERE NOT (me)-[:FRIEND]-(friend_of_friend) RETURN labels(friend_of_friend)")
这导致没有错误,但是我没有得到任何结果。我期待2条记录。
我的neo4j图包括:1个记录[会员A],其中id匹配{id},A有1个朋友B,B有2个朋友。我希望B的朋友能够通过查询返回。
这是我的简单测试用例:
public void testQuery(){
Member A = new Member("test@gmail.com");
Member B = new Member("testb@gmail.com");
Member friend = new Member("jau@gmail.com");
friend.addFriend(A);
friend.addFriend(B);
Member returnfriend = template.save(friend);
System.out.println("friend id " + returnfriend.getId());
Assert.assertNotNull(returnfriend.getId());
Assert.assertEquals(2, returnfriend.getFriends().size());
Member member = new Member("kim@gmail.com");
member.addFriend(returnfriend);
member = template.save(member);
//Page<Member> found = memberRepository.findByIdFriendsOfFriend(member.getId(), new PageRequest(0, 2));
Collection<Member> found = memberRepository.findByIdFriendsOfFriend(member.getId());
Assert.assertNotNull(found);
for(Member m : found){
if(m != null){
if(m.getEmail()!=null){
System.out.println(m.getEmail());
}
System.out.println(m.getId());
}else{
System.out.println("m is null");
}
}
Assert.assertEquals(2, found.size());
}
也许我如何定义我的数据模型会有所帮助:
@NodeEntity
public class Member {
@GraphId
private Long id;
@Indexed(unique = true)
private String email;
@RelatedTo(type = "FRIEND", direction = Direction.BOTH)
@Fetch
Set<Member> friends;
答案 0 :(得分:0)
id
属性值应该是字符串还是整数?您的Cypher查询会在{id}
周围添加引号,因此它只会匹配id具有字符串值的节点。请尝试删除{id}
周围的引号。
[EDITED]
此外,您更新的查询似乎没问题。我创建了一个成功找到两个friend_of_friend
节点的console。我已将{id}
替换为硬编码的数字(因为控制台不支持参数),并更改了`RETURN子句,以便您可以确定正在返回哪些节点。
MATCH (me:Member { id: 123 })-[:FRIEND*2..2]-(friend_of_friend:Member)
WHERE NOT (me)-[:FRIEND]-(friend_of_friend)
RETURN friend_of_friend.id