cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How to handle if else in neo4j and get nodes generically

12kunal34
Graph Fellow

Hello Everyone,

I need some help in writing cypher for my scenario.
My scenario is that i want to create lineage and data connection would be like this

ENTITY1<---[1]----ENTITY2<--[2]---ENTITY3<---[3]----ENTITY4----[4]---ENTITY5

I want to get all nodes from a single cypher but it has some test cases as given below

  • It may be possible that ENTITY2 is not there in Lineage, ENTITY1 directly connected to ENTITY3

  • It may be possible that Entities come twice in the Lineage like in below lineage ENTITY2 comes twice

ENTITY1<---[1]----ENTITY2<--[x]---ENTITY2<-----[2]----ENTITY3<---[3]----ENTITY4----[4]---ENTITY5

i used Apoc do.when and do.case but not got the desired output,

Please help me in this and let me know if you want to know further more about query.
i need these nodes for writing json in neo4j

Thanks in advance.

1 ACCEPTED SOLUTION

In your actual query, will you be starting from a particular node (or a set of nodes), or is your intent to run this for all nodes in your database and get all paths using these types?

As far as your type modeling, this is going to make your queries much much harder. Labels are meant to be the means by which you indicate type, and without a label on the nodes to ensure this, it will require an extra expansion per node (plus property access) to tell if the type of the node meets with what you want.

I would highly recommend refactoring your data model to use labels as types in your graph (remember that nodes can be multi-labeled). That would also make it much easier to use APOC path expander solutions for restricting the types of nodes you want in your path, and possibly for stopping expansion if you only want to expand out to PI nodes.

As an example of what you could do if you had nodes labeled with :DNA, :MIXDNA, :EXPRESSION, :HARVEST, and :PI, you could use this call using APOC path expanders, providing the labels of all the types to allow during the expansion, and using :PI labeled nodes as termination nodes in your filter, which would stop expansion and ensure all paths always end on :PI nodes:

(n:DNA{BARCODE:'abcde'})
CALL apoc.path.expandConfig(n, {relationshipFilter:'<ASSOCIATED', labelFilter:'MIXDNA | EXPRESSION | HARVEST | /PI'}) YIELD path
RETURN nodes(path) as pathNodes

View solution in original post

13 REPLIES 13

Could you provide the queries tried so far? It would help to understand the labels and relationship types involved.

Thanks Andrew.
Please find below very basic query foor my usecase(my whole query is quite complex)

MATCH(DNA:ENTITY)<-[:ASSOCIATED{PREDICATE:'E1_E2'}]-(MIXDNA:ENTITY)
 MATCH(MIXDNA)<-[:ASSOCIATED{PREDICATE:'E2_E3'}]-(EXPRESSION:ENTITY)
 MATCH(EXPRESSION)<-[:ASSOCIATED{PREDICATE:'E13_E4'}]-(HARVEST:ENTITY)
 MATCH(HARVEST)<-[:ASSOCIATED{PREDICATE:'E4_E5'}]-(PI:ENTITY)
 
 Return DNA,MIXDNA,EXPRESSION,HARVEST,PI

This query will work for a simple lineage that is like DNA--MIXDNA--EXPRESSION--HARVEST--PI

But if order will change or any entity is not there then my query will break.
order may be like DNA---EXRESSION---HARVEST---PI
or DNA---MIXDNA--EXPRESSION--HARVEST---HARVEST--PI

i use apoc case that will check that the entity type but don't have any idea how to embed it in my query

please help in this
please let me know if you want further info

Looks like this is meant to be a graph-wide query, as you aren't starting at any particular node. All nodes in your query are :ENTITY nodes, are there any other labels in play here? I don't understand how you can tell their role (PI, HARVEST, etc) if you're only using :ENTITY labels.

Is the only thing that provides structure to the paths you want the PREDICATE properties of the incoming :ASSOCIATED relationships? If so can you elaborate on the rules you want to enforce for these during expansion?

Are the PI:ENTITY nodes at the end leaf nodes (with no incoming :ASSOCIATED relationship to another :ENTITY node)?

I don't understand how you can tell their role (PI, HARVEST, etc) if you're only using :ENTITY labels.
Answer: there is a label entity type that is associated with Entity.it will tell the entity type of a perticular node.

entity<-[:belongs_to]-Entity_Type

Here in Entity_Type Label we have property that is ENTITY_TYPE_NAME which will tell the entity is PI,HARVEST or so on..

Is the only thing that provides structure to the paths you want the PREDICATE properties of the incoming :ASSOCIATED relationships? If so can you elaborate on the rules you want to enforce for these during expansion?

Predicate will tell the entity connections.
like DNA Connected with MIXDNA then predicate is DNA_DNA
DNA Connected with EXPRESSION then PREDICATE is DNA_EXPRESSION
and so on

and we can start from any node. we have to pass a unique entity id like this
(n:ENTITY{BARCODE:'abcde'})

In your actual query, will you be starting from a particular node (or a set of nodes), or is your intent to run this for all nodes in your database and get all paths using these types?

As far as your type modeling, this is going to make your queries much much harder. Labels are meant to be the means by which you indicate type, and without a label on the nodes to ensure this, it will require an extra expansion per node (plus property access) to tell if the type of the node meets with what you want.

I would highly recommend refactoring your data model to use labels as types in your graph (remember that nodes can be multi-labeled). That would also make it much easier to use APOC path expander solutions for restricting the types of nodes you want in your path, and possibly for stopping expansion if you only want to expand out to PI nodes.

As an example of what you could do if you had nodes labeled with :DNA, :MIXDNA, :EXPRESSION, :HARVEST, and :PI, you could use this call using APOC path expanders, providing the labels of all the types to allow during the expansion, and using :PI labeled nodes as termination nodes in your filter, which would stop expansion and ensure all paths always end on :PI nodes:

(n:DNA{BARCODE:'abcde'})
CALL apoc.path.expandConfig(n, {relationshipFilter:'<ASSOCIATED', labelFilter:'MIXDNA | EXPRESSION | HARVEST | /PI'}) YIELD path
RETURN nodes(path) as pathNodes

Thanks Andrew.
hope so it will work
let me check this and will let you know about this.
i will post my db schema as well so you have a better idea.
my final output is json which is creating by using these nodes values

Hey andrew.

Getting this error .
** Neo.DatabaseError.General.UnknownError

org/apache/commons/collections/IteratorUtils**

please help

What version of Neo4j are you using (and is it community or enterprise) and what version of APOC?

Neo4j Version: 3.3.5
Community Version
Apoc Version: 3.2.3.6

Okay, you're using the wrong version of APOC for your Neo4j version. For 3.3.5 you want to use APOC 3.3.0.3.

sorry my bad
i am using 3.2.5 neo4jversion

Ah, okay. You're using the correct APOC version, but there is a bug here that only manifests with the community version. If you are able to upgrade to a later Neo4j version (latest 3.3.x or 3.4.x) that would allow you to use an APOC version with that bug fixed, otherwise you may need to wait for us to get a fix done on the 3.2.x.x branch.

yeah Thanks andrew.
i read about it as well.
meanwhile i used some query and i am getting all nodes in a path that is DNA to PI.
now my main motive is to create json with it and format of json will be like this

PI{
PI Node Details,
HAR{
HARVEST Node details,
Exp{
Expression node detail,
Dna{
Dna Node details
}
}
}
}

i was able to do it earlier when i have only one node for each entity but if no. of nodes for particular entity is multiple and we don't know exact format of path then how to handle it.

Thanks.
Sorry for any Inconvenience .