Wolfgang-Schuetzelhofer / jcypher

Java access to Neo4J graph databases at multiple levels of abstraction
Apache License 2.0
86 stars 15 forks source link

Missing feature in WHERE predicate builder in JcCypher #41

Closed DonCziken closed 6 years ago

DonCziken commented 6 years ago

Use case is: fetch nodes by labels they are assigned with i.e. fetch all nodes which are of type BarrierArea OR BarrierInstance OR BarrierElement.

So based on above I'd like to build following cypher query using jCypher DSL:

MATCH (m) 
WHERE m:BarrierArea OR m:BarrierInstance OR m:BarrierElement 
RETURN m

However it seems that jCypher WHERE predicate builder is missing such an option. I had noticed that it is possbile to do following: WHERE.valueOf(n[0]).IN_list('BarrierArea', 'BarrierInstance', 'BarrierElement')

but this ends up to be much slower as it translates to following query, which does not scan by label, but do filtring:

PROFILE MATCH(n) where any(x IN labels(n) where x in ['BarrierArea', 'BarrierInstance', 'BarrierElement']) return n

I must say that I had found a workaround for this, which is following:

MATCH.node(n[0]).label("m:BarrierArea")
...
UNION.distinct()
MATCH.node(n[0]).label("m:BarrierInstance")
...
UNION.distinct()
MATCH.node(n[0]).label("m:BarrierElement")

but I'd much prefare to do it simple way (as first example), as workaround approach has some other disadventages for me.

So please let me know if that is possible (as maybe I missed something) and if not I would consider adding it :).

Wolfgang-Schuetzelhofer commented 6 years ago

Hi Krzysztof,

the solution is:

JcNode m = new JcNode("m"); clauses = new IClause[]{ MATCH.node(m), WHERE.has(m.label("BarrierArea")).OR().has(m.label("BarrierInstance")).OR().has(m.label("BarrierElement")), RETURN.value(m) };

This leads to the following cypher query:

MATCH (m) WHERE m:BarrierArea OR m:BarrierInstance OR m:BarrierElement RETURN m

Best regards, Wolfgang

On Tue, Aug 21, 2018 at 4:21 PM Krzysztof Gasior notifications@github.com wrote:

Use case is: fetch nodes by labels they are assigned with i.e. fetch all nodes which are of type BarrierArea OR BarrierInstance OR BarrierElement.

So based on above I'd like to build following cypher query using jCypher DSL:

MATCH (m) WHERE m:BarrierArea OR m:BarrierInstance OR m:BarrierElement RETURN m

However it seems that jCypher WHERE predicate builder is missing such an option. I had noticed that it is possbile to do founionunionunionllowing: WHERE.valueOf(n[0]).IN_list('BarrierArea', 'BarrierInstance', 'BarrierElement')

but this ends up to be much slower as it translates to following query, which does not scan by label, but do filtring:

PROFILE MATCH(n) where any(x IN labels(n) where x in ['BarrierArea', 'BarrierInstance', 'BarrierElement']) return n

I must say that I had found a workaround for this, which is following:

MATCH.node(n[0]).label("m:BarrierArea") ... UNION.distinct() MATCH.node(n[0]).label("m:BarrierInstance") ... UNION.distinct() MATCH.node(n[0]).label("m:BarrierElement")

but I'd much prefare to do it simple way (as first example), as workaround approach has some other disadventages for me.

So please let me know if that is possible (as maybe I missed something) and if not I would consider adding it :).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Wolfgang-Schuetzelhofer/jcypher/issues/41, or mute the thread https://github.com/notifications/unsubscribe-auth/AHI-359Tv0XXkJ8bjzNxuj5G4VijyWqwks5uTBdjgaJpZM4WF4Wb .

DonCziken commented 6 years ago

Perfect! Thank you very much!