Behavior of "in" predicate

Ran into an odd issue with "in". I found that "in" works with simple property values and array values. That is, the following are functionally equivalent when bar is a String value. But the "in" variant also works when bar is an array of strings.

where a.foo = b.bar
where a.foo in b.bar

This was nice because I could use the "in" construction in both cases. The code didn't need to know the type of bar in order to determine which cypher to use.

However, what I found was that as soon as I placed a unique constraint on foo, neo4j started to complain. With the index/constraint on foo it stopped accepting where a.foo in b.bar when bar was a string. The error was something about "expected list but found String".

The key here is that the behavior only changed when the unique constraint was on foo.

So two questions:

  1. Which is the "correct" behavior?
  2. Is there a as_list() function that can be used so that the predicate can "know" that it is working with a list?

Something that would evaluate like the following:

as_list('a') == as_list(['a']) == ['a']

Not urgent. It just causes complexity to bubble up in a way that Cypher rarely does.

IN shouldn't work with scalar values on the right side.

To make sure that your right side is a list you can try to use apoc.convert.toSet(value)