在START中使用@Query和索引查找

时间:2013-12-18 11:13:02

标签: neo4j cypher spring-data-neo4j

我有一个Spring Data Neo4j项目(版本2.3.2.RELEASE),其中有一个BesoinNode实体树。 BesoinNode包含“名称”字段和一组子项:

@NodeEntity
public class BesoinNode implements Besoin {

    @GraphId private Long id;

    //@Indexed(indexName = "indexBesoin", indexType = FULLTEXT) private String name;
    @Indexed(indexName = "indexBesoin") private String name;

    @RelatedTo(elementClass = BesoinNode.class, type = "hasChild", direction = OUTGOING)
    private Set<Besoin> besoins = new HashSet<Besoin>();

    // etc.
}

关联的存储库是:

public interface BesoinRepository extends GraphRepository<BesoinNode>, RelationshipOperationsRepository<BesoinNode>, NamedIndexRepository<BesoinNode> {

    // This query works
    @Query(value = "start parent=node({0}) match (parent)-[:hasChild]->(child) return child")
    Set<BesoinNode> findChildrenOf(Long id);

    // This query doesn't work
    @Query(value = "start parent=node:indexBesoin({name}) match (parent)-[:hasChild]->(child) return child")
    Set<BesoinNode> findChildrenOf(@Param("name") String name);

}

第一个查询有效,但要调用它,我首先需要检索节点的id,这是不必要的,我想避免的。这是第二个查询应该做的,但我不能让它工作。什么可能是错的?

如果我调用findChildrenOf("What a great name for a BesoinNode")方法,我会得到一个空指针异常。堆栈跟踪是:

java.lang.NullPointerException
    at org.apache.lucene.util.SimpleStringInterner.intern(SimpleStringInterner.java:54)
    at org.apache.lucene.util.StringHelper.intern(StringHelper.java:39)
    at org.apache.lucene.index.Term.<init>(Term.java:38)
    at org.apache.lucene.queryParser.QueryParser.getFieldQuery(QueryParser.java:643)
    at org.apache.lucene.queryParser.QueryParser.Term(QueryParser.java:1436)
    at org.apache.lucene.queryParser.QueryParser.Clause(QueryParser.java:1319)
    at org.apache.lucene.queryParser.QueryParser.Query(QueryParser.java:1245)
    at org.apache.lucene.queryParser.QueryParser.TopLevelQuery(QueryParser.java:1234)
    at org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:206)
    at org.neo4j.index.impl.lucene.IndexType.query(IndexType.java:300)
    at org.neo4j.index.impl.lucene.LuceneIndex.query(LuceneIndex.java:227)
    at org.neo4j.index.impl.lucene.LuceneIndex.query(LuceneIndex.java:238)
    at org.neo4j.cypher.internal.spi.gdsimpl.GDSBackedQueryContext$$anon$1.indexQuery(GDSBackedQueryContext.scala:87)
    at org.neo4j.cypher.internal.executionplan.builders.IndexQueryBuilder$$anonfun$getNodeGetter$2.apply(IndexQueryBuilder.scala:83)
    at org.neo4j.cypher.internal.executionplan.builders.IndexQueryBuilder$$anonfun$getNodeGetter$2.apply(IndexQueryBuilder.scala:81)
    at org.neo4j.cypher.internal.pipes.matching.MonoDirectionalTraversalMatcher.findMatchingPaths(MonodirectionalTraversalMatcher.scala:45)
    at org.neo4j.cypher.internal.pipes.TraversalMatchPipe$$anonfun$internalCreateResults$1.apply(TraversalMatchPipe.scala:38)
    at org.neo4j.cypher.internal.pipes.TraversalMatchPipe$$anonfun$internalCreateResults$1.apply(TraversalMatchPipe.scala:35)
    at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
    at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
    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:86)
    at org.neo4j.cypher.internal.ClosingIterator.hasNext(ClosingIterator.scala:35)
    at org.neo4j.cypher.PipeExecutionResult.hasNext(PipeExecutionResult.scala:157)
    at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
    at scala.collection.convert.Wrappers$IteratorWrapper.hasNext(Wrappers.scala:29)
    at org.neo4j.cypher.PipeExecutionResult$$anon$1.hasNext(PipeExecutionResult.scala:73)
    at org.neo4j.helpers.collection.IteratorWrapper.hasNext(IteratorWrapper.java:42)
    at org.neo4j.helpers.collection.IteratorUtil.addToCollection(IteratorUtil.java:351)
    at org.neo4j.helpers.collection.IteratorUtil.addToCollection(IteratorUtil.java:370)
    at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.dispatchQuery(GraphRepositoryQuery.java:104)
    at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.execute(GraphRepositoryQuery.java:81)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:323)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy29.findChildrenOf(Unknown Source)

任何帮助都会受到赞赏,因为我在两天之后就在解决这个问题。

1 个答案:

答案 0 :(得分:1)

好吧,它突然起作用,问题在于我混合了两种索引查找样式。

我需要为Lucene指定“名称”。所以,而不是:

// This query doesn't work
@Query(value = "start parent=node:indexBesoin({name}) match (parent)-[:hasChild]->(child) return child")
Set<BesoinNode> findChildrenOf(@Param("name") String name);

我需要:

// This query works
@Query(value = "start parent=node:indexBesoin(name={name}) match (parent)-[:hasChild]->(child) return child")
Set<BesoinNode> findChildrenOf(@Param("name") String name);

区别在于“indexBesoin(name = {name})”而不仅仅是“indexBesoin({name})”。

似乎有不同的方法在Spring Data Neo4j中使用索引,这很令人困惑。