I am trying to find the index of an item in a collection of custom objects (so not a collection of nodes). I am using apoc.coll.indexOf(collection, object)
, but it is returning -1
instead of the actual index.
The queries below show the problem. The first query creates two test nodes, each with an array of booleans called someArray
. The second query matches all nodes with the given label, collects them into a variable called collection
, and lastly tries to get the index of an object with the same someArray
field as an empty array. I expected it to return either 0
or 1
(depending on how the collection is sorted), but it returns -1
.
CREATE (test:Test { someArray: [true, false, true] })
CREATE (test2:Test { someArray: [] })
MATCH (n:Test)
WITH COLLECT({
someArray: n.someArray
}) as collection
RETURN apoc.coll.indexOf(collection, { someArray: [] }) // Returns -1
How do I find the correct index in this case? If this is intended behaviour (for example, comparing arrays by reference) can you point me to the documentation page?
(this is Neo4j 4.4)
This seems to be caused by a weird bug in apoc.coll.indexOf.
This query:
MATCH (n:Test)
WITH COLLECT({
someArray: n.someArray
}) as collection
RETURN collection
returns this:
[{someArray: [true, false, true]}, {someArray: []}]
If you hardcode that list into this query (I tested on neo4j 5.5):
RETURN apoc.coll.indexOf([{someArray: [true, false, true]}, {someArray: []}], {someArray: []})
the result is 1
.
So apoc.coll.indexOf
unexpectedly treats collection
differently than the "same" hardcoded list.
You should create a neo4j issue about this odd behavior.
[UPDATE]
Workaround (where the test value is passed in as the $val parameter):
MATCH (n:Test)
WITH COLLECT(
{someArray: n.someArray}
) AS collection
RETURN [i IN RANGE(0, SIZE(collection)-1) WHERE collection[i] = $val | i] AS result
result
is a possibly-empty list of matching indexes. This query is similar to @CharchitKapoor's, but we return all matching indexes.