I would like to perform a depth first search on my graph and so, get all the paths existing from a given node ('N1456' in my example), and all the nodes of theses path must have the same property "PROPERTY_TO_FILTER". Typically, my graph is composed of two types of node, and two types of relations. For now, I tested the following request :
WITH "
MATCH (my_node{name : 'N1456'})
CALL apoc.path.expandConfig(protein, {uniqueness:'NODE_GLOBAL', bfs : FALSE}) YIELD path
WITH path, my_node, last(nodes(path)) as subgraph
WHERE my_node<> subgraph and my_node.my_property CONTAINS 'PROPERTY_TO_FILTER'
RETURN nodes(path), length(path) AS len
ORDER BY len DESC" AS query
CALL apoc.export.json.query(query, "my_results.json", {})
YIELD properties, data
RETURN properties, data;
However, the results are not the ones attended. I get a list of paths but only the first node has the property "PROPERTY_TO_FILTER" ; this filter is not taken into account for the other nodes...
I guess I should put a filter at apoc.path.expandConfig level, but I see in the documentation that this is only possible to filter the node label, not the node properties.
MATCH (n:Node {id: 0})
CALL apoc.path.expandConfig(n, {uniqueness: 'NODE_GLOBAL', bfs: FALSE}) YIELD path
WHERE all(node IN nodes(path) WHERE node.my_property CONTAINS 'PROPERTY_TO_FILTER')
RETURN nodes(path), length(path) AS len
ORDER BY len DESC
Thanks for your answer.
However I don't get the attempted result.
It looks like the DFS isn't launched :-/
I guess that it is maybe due to the fact that the graph has the following structure :
n_Node -> rel:a -> m_Node -> rel:b -> n_Node
and m_Node hasn't the property "PROPERTY_TO_FILTER". So, I'd like to perform my DFS on all the nodes of the graph, using the filter "PROPERTY_TO_FILTER" on nodes n_Nodes, but systematically taking all the nodes between them "m_Node".
So you only want the first node and the last node of the path to have the property "PROPERTY_TO_FILTER"? In my query the all() predicate make sure all the nodes of the path meet the condition, that's why your path is not returned.
I'd like that all the nodes "n" (Country) have the property value "PROPERTY_TO_FILTER", but I also want the nodes located into each pair of nodes Country (Town). Actually, the "Town" nodes doesn't have the same properties as "Country" ones. This is why I cannot filter them (and I don't want to :) ).
I think I get it, in the WHERE clause, if it's a Country it will check the property value otherwise it will ignore the node:
MATCH (n:Country {name: "France"})
CALL apoc.path.expandConfig(n, {uniqueness: 'NODE_GLOBAL', bfs: FALSE}) YIELD path
WHERE all(node IN nodes(path) WHERE ("Country" IN labels(n) AND node.my_property CONTAINS 'PROPERTY_TO_FILTER') OR ("Town" IN labels(n)))
RETURN nodes(path), length(path) AS len
ORDER BY len DESC
LOAD CSV WITH HEADERS FROM 'file:///neo4j_exp.csv' AS row
MERGE (p:Country{name : row.IDA, id: row.COUNTRYA, groupe: row.Groupe_ATLAS})
MERGE(s:Town {name : row.RESIDUE, id :row.index_residue})
MERGE (m:Country {name : row.IDB, id: row.COUNTRYB, residue_exp: row.RESIDUE_EXP, groupe: row.Groupe_Experimental})
WITH p,s,m,row
CREATE (p)-[rel:action]->(s)-[relation:on]->(m)
RETURN rel, relation;
As you can see, the filter is then performed on the value contained in "groupe" parameter, associated to Country nodes, which can have the values COND1_COMP1, ATLAS, COND1_COMP2, etc.
So I'd like to find the paths encompassing the Country nodes having one specific "groupe" (COND1_COMP1 as an example), linked by nodes Town, without any condition on them.
Do you have a start node I can use? I think there is a problem with the data. But I'm sure the query answer the solution:
MATCH (n:Country)
WHERE n.groupe_exp = "COND1_COMP1"
CALL apoc.path.expandConfig(n, {uniqueness: 'NODE_GLOBAL', bfs: FALSE}) YIELD path
WHERE all(n IN nodes(path) WHERE ("Town" IN labels(n)) OR ("Country" IN labels(n) AND n.groupe_exp = "COND1_COMP1"))
RETURN nodes(path), length(path) AS len
ORDER BY len DESC
This first node you gave me doesn't have the property groupe. I really think the data is not properly loaded into your database. You should have one file for nodes and another one for relations then load nodes then relationships.
MERGE clause overwrite everything in the node. So normally, you MERGE a node based on its id then SET its properties like MERGE (c:Country {id: row.COUNTRYA}) SET c.name = row.IDA, etc.
That's why, it's better to have a file for nodes and another one for relationships.
WITH "MATCH (n:Country{name : 'P11309'})
WHERE n.groupe IN ['ATLAS','COND3_COMP1']
CALL apoc.path.expandConfig(n, {uniqueness:'NODE_GLOBAL', bfs : FALSE}) YIELD path
WHERE all(node IN nodes(path) WHERE ('Town' IN labels(n)) OR ('Country' IN labels(n) AND n.groupe in ['ATLAS','COND3_COMP1']))
RETURN nodes(path), length(path) AS len
ORDER BY len DESC" AS query
CALL apoc.export.json.query(query, "P11309-start-'ATLAS','COND3_COMP1'.json", {})
YIELD properties, data
RETURN properties, data;
It gaves me 7212394 properties, but again I can see other "groupe" property value than COND3_COMP1 and ATLAS in my json. It is so weird..