简体   繁体   中英

Neo4J IN operator

I am having trouble using the IN operator in a Cypher query, using the embedded Java API. It would appear that you are unable to utilize the IN operator with an identifier other than the entity(ies) retrieved in the start clause.

For example, here is my query:

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

I can utilize the IN operator when filtering on a property of n , but it fails with the following exception when I execute the above query and attempt to call hasNext() on the Iterator returned from columnAs("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)

Am I correct in my assumption that you cannot use the IN operator on something other than n in my example? Is this a bug, or is this by design?

I wanted to answer my own question, in case other people are having similar issues. There are a couple things that I want to adress in reference to the above example:

Per this discussion in the neo4j Google Group forum

  • I added the HAS() function to the WHERE clause
  • I also changed the array values to use a single quote ( ' ) instead of the previous double quotes

So my new example query looks like this:

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

This worked as expected.

After making the above edits, I converted my query to use parameters (which if JDBC has taught me anything, is the correct way to perform queries like this). That query looked like this:

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

This also worked correctly.

The IN operator is not terribly well documented at the moment, which is understandable since it is fairly new to the neo4j project, but I wanted to make sure this was answered in case anybody else is having similar troubles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM