Skip to content

3.14 Narrowing at the source — membership pushdown

MATCH (s:DiseaseScope {registryQuery: 'Long COVID'})-[:HAS_TRIAL_SEARCH]->(r:TrialSearchRun)
MATCH (r)-[:RETURNED]->(t:ClinicalTrial)
WHERE t.overallStatus = 'RECRUITING' AND 'OLDER_ADULT' IN t.ageGroups
RETURN t.nctId, t.title

Both conditions can reach the registry, so the fetch returns the trials that match instead of every trial for the disease. Nothing about the result depends on that: if the source could not apply either filter, the same rows would come back after filtering the materialized graph, and only the number of records fetched would differ.

Note the direction of the membership test. 'OLDER_ADULT' IN t.ageGroups asks whether the record’s list contains a value; t.overallStatus IN ['RECRUITING', 'COMPLETED'] asks whether the record’s value is in a list you wrote. They are different questions, and only the first describes a list-valued property.

The second question has two spellings, and they push alike. t.overallStatus = 'RECRUITING' OR t.overallStatus = 'COMPLETED' is the set IN ['RECRUITING', 'COMPLETED'] written out, and it reaches a producer declaring an IN rule exactly as the list does. An OR that mixes properties (t.overallStatus = 'RECRUITING' OR t.phase = 'PHASE3'), reaches across variables, or has a non-equality arm pushes nothing and is applied in the graph: the rows are the same, the fetch is broad.