COLLECT Return bug (CYPHER25)

This is a fragment of a query I am modifying (originally I had 1 MATCH but my graph has changed and I need to separate it into 2:

MATCH (P:Node { uuid: 'some_uuid' })
      -[a:someRelLabel1*0..1]->(Q:ALabel)
MATCH (P)-[a1:someOtherRelLabels*0..1]->(Q1:AnotherLabel)
   ... more statement
RETURN COLLECT (DISTINCT P) + (all other nodes) AS retNodes
       COLLECT (DISTINCT a) + (DISTINCT a1) + (all other rels) AS retRels

This is what retRels contains:

       
[[], <-- this seems to be a bug? 
[
{
identity: 22400,
start: 20093,
end: 20092,
type: "someRelLabel1", // <-- this is the label from "DISTINCT a"
properties: {},
elementId: "5:c6da763b-b380-48b5-86f8-cfa7cba1d4f4:22400",
startNodeElementId: "4:c6da763b-b380-48b5-86f8-cfa7cba1d4f4:20093",
endNodeElementId: "4:c6da763b-b380-48b5-86f8-cfa7cba1d4f4:20092"
}
], 
...

For context, this code:

foreach (var rel in cursor.Current["retRels"].As<List<List<IRelationship>>>())

now throws this exception (before Q/Q1 and a/a1 which were in the same line)

System.InvalidCastException: Unable to cast object of type `Neo4j.Driver.Internal.Types.Relationship` to type `System.Collections.Generic.List`1[Neo4j.Driver.IRelationship]`

It gets even weirder, if I change my collect to:

COLLECT(DISTINCT a + a1 + b + c + d + e + f) AS retRels
  • The old Neo4J desktop fetches me all the relationships
  • The new Neo4J desktop misses any new relationship that wasn’t inserted before the change, but I can’t see the content - it doesn’t fetch me any details on ids
  • The c# driver has missed all the new relationships as well,

@joshcornejo

if you revert to the prior cypher version and preface your queries with

cypher 5 

do you get expected results or one in the same when using cypher 25. just trying to determine where the failure begins

prefix with CYPHER 5 in new Desktop … still same results:

[[[:hasRule {type: ""}]], [:repercussion], [:target], [], [[:asset]], [], [], []]

Strange enough, the “count” of sets seems correct (the empty brackets)

So keep in mind that when you have a var-length pattern with 0 as the lower bound (as in your MATCH (P)-[a1:someOtherRelLabels*0..1]->(Q1:AnotherLabel) line) that if P and Q1 could possibly be the same node (if the label there is also present on P) then it will match to a path where P and Q1 are the same, and the list of relationships (a1) for that path is empty (a1 must be a list, as it’s part of var-length relationship; empty because the lower bound allows a pattern where no relationship exists and the end nodes are the same node).

As a simple example, to run on an empty db:

CREATE (:Start:Node {id:1})-[:REL {relId:1}]->(:End:Node {id:2});

Now match and collect rels:

MATCH (s:Start)-[a:REL*0..1]->(e:Node)
RETURN collect(DISTINCT a)

The result is:

[[], [[:REL {relId: 1}]]]

The first element of the empty list is an empty list, when there is no rel and the start and end nodes are the same.

But I’m getting different results to the same query between the old Desktop and the new one?

Even before this query change, it looked like this:

MATCH (P:Node { uuid: 'some_uuid' })
       -[a:someRelLabel1|someOtherRelLabels*0..1]->(Q:ALabel) 
    ... more statement 
RETURN COLLECT (DISTINCT P) + (all other nodes) AS retNodes       
COLLECT (DISTINCT a) + (all other rels)

And I didn’t have this empty set result …

Was the data the same? The only way you would get an empty set result is if the labels are such that P and Q could be the same node. If it doesn’t have the labels necessary for that, then you won’t have that result.

P is not the same as Q - the query below works “fine” (but I don’t want any subsequent nodes from Q:ALabel (i had to make subsequent relationships wildcards) so that’s why there are now 2 matches:

Original:

MATCH (P:Node { uuid: 'some_uuid' })
        -[a:someRelLabel1|someOtherRelLabels*0..1]->(Q:ALabel|AnotherLabel)

Modified:

MATCH (P:Node { uuid: 'some_uuid' })
       -[a:someRelLabel1*0..1]->(Q:ALabel) 
MATCH (P)-[a1:someOtherRelLabels*0..1]->(Q1:AnotherLabel)

Data the same, database the same, below is the same query ran on 1.6.2 and 2.x":

You can see it doesn’t fetch relationship 23260 (even though is the same type as 22738), and the results as a table are all different:

Further, C#’s results are the same as Desktop2 - empty relationships without content at the front and back and giving a casting exception.

Here, the top of the image is with 2 MATCH clauses / the bottom of the image is with 1 MATCH … 23260 is still missing.

FYI, I’ve modelled the query with 1 MATCH and a WHERE type(b) <> ‘AnotherLabel’ and I get output discrepancies between Dv2 (top) and Dv1 (bottom) - where bottom returns what I want (top still misses a the bottom left relationship.

(Everything is up-to-date - desktop and db)

My data stored looks like the desktop v1 (node 0.1 has 2 relationships 22740 and 22400, 20162 has 1 relationship to 20650)

MATCH (P:Node { uuid: 'some_uuid' })
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[b]->(R)
      ... more statements
WHERE type(b) <> 'AnotherLabel'

If I don’t have the where clause - i get the same results on both desktops, if I have the where clause, then I get different results (so i assume v1 has that “bring relationships anyway”)

If I change to:

MATCH (P:Node { uuid: 'some_uuid' })
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
WITH P, Q, a
OPTIONAL MATCH (Q)-[b]->(R)
WHERE type(b) <> 'AnotherLabel'

I get the same results.

If I try:

MATCH (P:Node { uuid: 'some_uuid' })
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[b:*0..1]->(R)
      ... more statements
WHERE type(b) <> 'AnotherLabel'

I get an error “Invalid input '*', …”.

But this works:

MATCH (P:Node { uuid: 'some_uuid' })
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[*0..1]->(R)
      ... more statements

… but in this case I have lost relationship b and the ability to fetch it …

I am sure there is a bug somewhere … after much tinkering

MATCH (P:Node { uuid: 'some_uuid' })       
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[b*0..1]->(R)

and

MATCH (P:Node { uuid: 'some_uuid' })       
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[b*0..1]->(R)

and

MATCH (P:Node { uuid: 'some_uuid' })       
      -[a:someRelLabel1*0..1]->(Q:ALabel|AnotherLabel)
      -[b*0..1]->(R)
...
WHERE NOT (Q)-[:hasRule]->(R)

should return the same results for 2 of my 3 graphs … but when added the WHERE clause it inserted an empty []… which generated the:

I introduced code:

var tmpList = cursor.Current["retRels"].As<List<List<object>>>().Where(innerList => innerList.Count != 0).ToList();

to “clear” those empty lists from the result set in C#