cancel
Showing results for 
Search instead for 
Did you mean: 

how create cypher query with conditional filters

rullyalves
Node

I'm working on a model of relationships where a Profile has Preferences and Preferences have Filters, some of these Filters can be required or not, based on that I want to filter and bring the results of the filters, a requirement is always to try to filter even the optional filters and bring all data in case an optional filter returns empty, I stumbled on this query that apparently works, but I don't know if it's the best way:
model: Untitled graph - Arrows

query:


MATCH 
(p: Profile{id: "b6f28612-7b5d-4365-b7b5-87a3f1587885"}),
(p)-->(address: Address),
(p)-->(pref:Preferences)
        
MATCH (p2:Profile)--(p2address:Address) 
WHERE point.distance(point({latitude: address.latitude, longitude: address.longitude}), point({latitude: p2address.latitude, longitude: p2address.longitude})) <= pref.distance
AND (p2.age >= pref.minAge AND p2.age <= pref.maxAge)
AND NOT (p)--(:Like|Deslike|Match|Block)--(p)
WITH p2 as allData, pref

OPTIONAL MATCH (pref)-->(filter: GenderFilter)
OPTIONAL MATCH (filter)-->(x: Gender)<--(p2)

WITH p2 as filtered, filter, allData, pref   

CALL apoc.do.when(
filter IS NOT NULL AND filter.isRequired, 
"RETURN filtered as result",
"WITH filtered, allData, (count(filtered) = 0) as isEmpty CALL apoc.do.when(isEmpty, 'RETURN allData as result', 'RETURN filtered as result', {allData: allData, filtered: filtered}) YIELD value WITH value.result as result RETURN result ",
{filtered: filtered, allData: allData}
)
YIELD value   
      
WITH value.result as resultSet, pref
WHERE resultSet IS NOT NULL
WITH resultSet as allData, pref

OPTIONAL MATCH (pref)-->(filter: RelationTypeFilter)
OPTIONAL MATCH (filter)-->(x: RelationType)<--(p2)
WITH p2 as filtered, filter, allData, pref

CALL apoc.do.when(
filter IS NOT NULL AND filter.isRequired, 
"RETURN filtered as result",
"WITH filtered, allData, (count(filtered) = 0) as isEmpty CALL apoc.do.when(isEmpty, 'RETURN allData as result', 'RETURN filtered as result', {allData: allData, filtered: filtered}) YIELD value WITH value.result as result RETURN result ",
{filtered: filtered, allData: allData}
)
YIELD value   

WITH value.result as resultSet, pref
WHERE resultSet IS NOT NULL
WITH resultSet as allData, pref
 
WHERE allData.id <> "b6f28612-7b5d-4365-b7b5-87a3f1587885"
         
RETURN allData LIMIT 10



1 REPLY 1

Bertel
Node

Conditional cypher execution with subqueries might be of interest if you want to optimize the query: https://neo4j.com/developer/kb/conditional-cypher-execution/

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online