rmlan
rmlan

Reputation: 4657

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?

Upvotes: 3

Views: 9437

Answers (1)

rmlan
rmlan

Reputation: 4657

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.

Upvotes: 5

Related Questions