Neo4J IN 运算符

rml*_*lan 3 java neo4j

我在使用嵌入式 Java API 的 Cypher 查询中使用 IN 运算符时遇到问题。您似乎无法将 IN 运算符与子句中检索到的实体以外的标识符一起使用start

例如,这是我的查询:

start n=node(someLongNodeId) 
match n--m 
where m.gnid? IN [\"someStringId\",\"otherStringId\"] 
return m
Run Code Online (Sandbox Code Playgroud)

在过滤 的属性时,我可以使用 IN 运算符,但当我执行上述查询并尝试调用从 返回的n值时,它会失败并出现以下异常:hasNext()IteratorcolumnAs("m")

Exception in thread "main" java.lang.RuntimeException
    at org.neo4j.cypher.internal.pipes.matching.MiniMap.newWith(ExpanderStep.scala:172)
    at org.neo4j.cypher.internal.pipes.matching.MiniMap.newWith(ExpanderStep.scala:155)
    at org.neo4j.cypher.internal.commands.InCollection$$anonfun$isMatch$1.apply(InCollection.scala:39)
    at org.neo4j.cypher.internal.commands.InCollection$$anonfun$isMatch$1.apply(InCollection.scala:38)
    at scala.collection.LinearSeqOptimized$class.exists(LinearSeqOptimized.scala:79)
    at scala.collection.immutable.List.exists(List.scala:45)
    at org.neo4j.cypher.internal.commands.AnyInCollection$$anonfun$seqMethod$2.apply(InCollection.scala:71)
    at org.neo4j.cypher.internal.commands.AnyInCollection$$anonfun$seqMethod$2.apply(InCollection.scala:71)
    at org.neo4j.cypher.internal.commands.InCollection.isMatch(InCollection.scala:38)
    at org.neo4j.cypher.internal.commands.And.isMatch(Predicate.scala:83)
    at org.neo4j.cypher.internal.pipes.matching.FilteringIterable$FilteringIterator.spoolToNextInLine(FilteringIterable.scala:55)
    at org.neo4j.cypher.internal.pipes.matching.FilteringIterable$FilteringIterator.<init>(FilteringIterable.scala:34)
    at org.neo4j.cypher.internal.pipes.matching.FilteringIterable.iterator(FilteringIterable.scala:72)
    at org.neo4j.cypher.internal.pipes.matching.FilteringIterable.iterator(FilteringIterable.scala:27)
    at scala.collection.JavaConversions$IterableWrapperTrait$class.iterator(JavaConversions.scala:557)
    at scala.collection.JavaConversions$IterableWrapper.iterator(JavaConversions.scala:583)
    at scala.collection.JavaConversions$IterableWrapper.iterator(JavaConversions.scala:583)
    at org.neo4j.kernel.impl.traversal.TraversalBranchWithState.expandRelationshipsWithoutChecks(TraversalBranchWithState.java:70)
    at org.neo4j.kernel.impl.traversal.TraversalBranchImpl.expandRelationships(TraversalBranchImpl.java:104)
    at org.neo4j.kernel.impl.traversal.StartNodeTraversalBranch.next(StartNodeTraversalBranch.java:47)
    at org.neo4j.kernel.impl.traversal.AsOneStartBranch.next(AsOneStartBranch.java:100)
    at org.neo4j.kernel.PreorderDepthFirstSelector.next(PreorderDepthFirstSelector.java:52)
    at org.neo4j.kernel.impl.traversal.TraverserIterator.fetchNextOrNull(TraverserIterator.java:65)
    at org.neo4j.kernel.impl.traversal.TraverserIterator.fetchNextOrNull(TraverserIterator.java:34)
    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$22.hasNext(Iterator.scala:388)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at org.neo4j.cypher.PipeExecutionResult.hasNext(PipeExecutionResult.scala:138)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
    at scala.collection.JavaConversions$IteratorWrapper.hasNext(JavaConversions.scala:562)
    at com.awesomecompany.data.neo.NeoTestDriver.performBidirectionalQuery(NeoTestDriver.java:122)
    at com.awesomecompany.data.neo.NeoTestDriver.main(NeoTestDriver.java:44)
Run Code Online (Sandbox Code Playgroud)

我的假设是否正确,即您不能在n我的示例中以外的其他地方使用 IN 运算符?这是一个错误,还是设计使然?

rml*_*lan 5

我想回答我自己的问题,以防其他人也遇到类似的问题。关于上面的例子,我想解决一些问题:

根据neo4j Google Group 论坛中的讨论

  • 我将 HAS() 函数添加到 WHERE 子句中
  • 我还更改了数组值以使用单引号 ( ') 而不是之前的双引号

所以我的新示例查询如下所示:

start n=node(someLongNodeId) 
match n--m 
where HAS(m.gnid) AND m.gnid IN ['someStringId','otherStringId'] 
return m
Run Code Online (Sandbox Code Playgroud)

这正如预期的那样。

进行上述编辑后,我将查询转换为使用参数(如果 JDBC 教会了我任何东西,那么这是执行此类查询的正确方法)。该查询如下所示:

start n=node({nodeId}) 
match n--m 
where HAS(m.gnid) AND m.gnid IN {otherIds}
return m
Run Code Online (Sandbox Code Playgroud)

这也工作正常。

IN 运算符目前还没有很好的文档记录,这是可以理解的,因为它对于 neo4j 项目来说相当新,但我想确保这个问题得到解答,以防其他人遇到类似的麻烦。