Bug in cypher when filtering collection ?

34 views
Skip to first unread message

Tom Zeppenfeldt

unread,
Apr 17, 2014, 4:21:20 PM4/17/14
to ne...@googlegroups.com
I'm running a cypher query containing this:

MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) 
WITH tt,tu,tv ORDER BY tt.id,tv.version DESC
WITH tt,COLLECT([type(tu),tv.version]) AS tus
RETURN tt.id, [x IN tus WHERE x[1]=2 | [x[0],x[1]]] AS filtered

which produces correct results.  

However, if I replace the  x[1]=2  in the last line by x[1]>=2  I get an error
Type mismatch: expected String but was Integer (line 7, column 37)
"RETURN tt.id, [x IN tus WHERE x[1]>=2 | [x[0],x[1]]] AS filtered"

Tom Zeppenfeldt

unread,
Apr 18, 2014, 3:07:25 AM4/18/14
to ne...@googlegroups.com

Tom Zeppenfeldt

unread,
Apr 18, 2014, 11:58:42 AM4/18/14
to ne...@googlegroups.com
x[1]<>2  works too .. must be something with the <=  <  >  and  >= operators ? 

Lundin

unread,
Apr 18, 2014, 6:01:51 PM4/18/14
to ne...@googlegroups.com
Hi,

Yeah something seems to happen during your ,COLLECT([type(tu),tv.version]) AS tus so it seems.

The general filter function works with the comparision, like this one:

MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,tv ORDER BY tt.id,tv.version DESC WITH tt,type(tu) AS Rel,collect(tv) AS tus RETURN tt.id,[x IN tus WHERE x.version>2 | x] AS filtered,Rel


So, Is it mandatory for you to have the output exactly like you had it? Otheriwse these works similar

MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,tv ORDER BY tt.id,tv.version DESC WITH tt,type(tu) AS Rel,collect(tv) AS tus RETURN tt.id,[x IN tus WHERE x.version>2 | x] AS filtered,Rel


MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,tv ORDER BY tt.id,tv.version DESC WITH tt,type(tu) AS Rel,collect(tv) AS tus RETURN tt.id,collect([filter(x IN tus WHERE x.version>2), Rel]) AS filtered
or more similar your original output

MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,tv ORDER BY tt.id,tv.version DESC WITH tt,type(tu) AS Rel,collect(tv) AS tus RETURN tt.id,collect([[x IN tus WHERE x.version>2 | x.version], Rel]) AS filtered

Lundin

unread,
Apr 18, 2014, 6:37:41 PM4/18/14
to ne...@googlegroups.com
Another not so nested output might be

MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,collect(tv) AS TvCollection WITH tt,COLLECT([type(tu),[x IN TvCollection WHERE x.version>=2 | x.version]]) AS tus RETURN tt.id,head(tus) AS filtered 



MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion)
WITH tt,tu,collect(tv) AS TvCollection
WITH tt,COLLECT([type(tu),[x IN TvCollection 
                                 WHERE x.version=2 | x.version]]) AS tus
RETURN tt.id,head(tus) AS filtered

Lundin

unread,
Apr 18, 2014, 7:25:12 PM4/18/14
to ne...@googlegroups.com
Hi again, i tested some more variants.

Just looking at the actual parser error about string/integer missmatch i tried this one and it actually worked: (note the typecasting in the comparison)

MATCH (p:project { name: "ProjA" })-[:CURRENT|PREV*]->(pv:projversion)-[pu:ADD|REMOVE]->(pt:projtransition)<-[:HASALIAS]-(tt:transition) WHERE pv.version <= 1 WITH tt,pv,type(pu) AS putype ORDER BY tt.id,pv.version DESC WITH tt,HEAD(collect(putype)) AS lastputype WHERE lastputype = "ADD" MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) WITH tt,tu,tv ORDER BY tt.id,tv.version DESC WITH tt,COLLECT([type(tu), tv.version]) AS tus RETURN tt.id,[x IN tus WHERE str(x[1])>=str(2)| [x[0], x[1]]] AS filtered


Den torsdagen den 17:e april 2014 kl. 22:21:20 UTC+2 skrev Tom Zeppenfeldt:

Tom Zeppenfeldt

unread,
Apr 19, 2014, 6:52:33 AM4/19/14
to ne...@googlegroups.com
Hi Lundin,

Thanks a lot for your replies and efforts to find a workaround. I finally decided to use the explicit typecasting, and build the rest of the cypher statement which now looks as this:

MATCH (p:project {name: "ProjA"})-[:CURRENT|PREV*]->(pv:projversion)-[pu:ADD|REMOVE]->(pt:projtransition)<-[:HASALIAS]-(tt:transition) WHERE pv.version <= 1 
WITH tt,pv,type(pu) AS putype  ORDER BY tt.id,pv.version DESC 
WITH tt,HEAD(collect(putype)) AS lastputype WHERE lastputype = "ADD"
MATCH (tt)<-[tu:ADD|REMOVE]-(tv:tocversion) 
WITH tt,tu,tv ORDER BY tt.id,tv.version DESC
WITH tt,COLLECT([type(tu),tv.version]) AS tus
WITH tt, HEAD([x IN tus WHERE str(x[1])<=str(4) | [x[0],x[1]]]) AS lastupdate WHERE lastupdate[0] <> "ADD"
RETURN tt.id as conflicting

Which returns nodes that are conflicting (i.e. were not yet created or were already deleted) in specific versions of two different networks.
Do you agree with me that this typecasting should not be necessary and that cypher internally does some weird things that prevents comparing of integer values ?

Lundin

unread,
Apr 19, 2014, 12:27:25 PM4/19/14
to ne...@googlegroups.com
Great to hear that it works Tom, looks good! Have you put index in place and are you doing parametered queries in order for better performance as well ? (or mabey it works good "as is" ?). For the typecasting, well yes..but i guess some kind of type assertion needs to be in place on the server anyhow but souldnt be needed for the end-user to explicit do the typecasting so i guess i agree with that. Hopefully someone from the Neo4j team can chime in.
Reply all
Reply to author
Forward
0 new messages