Hi everyone please help me tune this cypher query below.
MATCH (s:Survey { is_active: true })
with s SKIP 0 LIMIT 25
MATCH (s)<-[:HAS_CLIENT]-(client:Client)
MATCH (s)-[:SAMPLE_TYPE]->(st:ProjectSettingElement)
MATCH (s)-[:CATEGORY]->(pc:ProjectSettingElement)
MATCH (s)-[:PROJECT_MODE]->(pmode:ProjectSettingElement)
OPTIONAL MATCH (s)-[:SALES_PERSON]->(sp:StaffUser)
OPTIONAL MATCH (s)-[:PROJECT_MANAGER]->(pman:StaffUser)
OPTIONAL MATCH (s)-[:CREATED_BY]->(staff:StaffUser)
OPTIONAL MATCH (s)-[:USES_CURRENCY]->(cy:ProjectSettingElement)
WITH DISTINCT s, sp, staff, pman, cy, st, pc, pmode, client
OPTIONAL MATCH (tot:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WHERE (tot)-[:HAS_COMPLETE_STATUS]->()
WITH DISTINCT s, sp, staff, pman, cy, st, pc, pmode, client,tot
OPTIONAL MATCH (total_reach:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH DISTINCT count(total_reach) as total, s, sp, staff, pman, cy, st, pc, pmode, client,tot
WITH CASE WHEN COUNT(tot) > 0 THEN ((SUM(toFloat(coalesce(tot.duration,0)))/1000)/60)/COUNT(tot) ELSE 0 END as avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client
//INCOMPLETE
OPTIONAL MATCH (incpm:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WHERE NOT (incpm)-[:HAS_COMPLETE_STATUS]->()
WITH count(incpm) as incomplete, total, s, sp, staff, pman, cy, st, pc, pmode, client, avg_loi
//REACHED
OPTIONAL MATCH (pre_cmp:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(pre_cmp) as reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
//RETURNED
OPTIONAL MATCH (ret:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_COMPLETE_STATUS]->()
WHERE (ret)-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(ret) as returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
//SPEEDER
OPTIONAL MATCH (speeder:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_RESTRICTION_STATUS]->(:Status{name:"speeder"})
WITH count(speeder) as speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (cmp:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_COMPLETE_STATUS]->(:Status{name:"complete"})
WHERE (cmp)-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(cmp) as complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (qta:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_COMPLETE_STATUS]-(:Status{name:"quotafull"})
WHERE (qta)-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(qta) as quotafull, complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (trm:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_COMPLETE_STATUS]-(:Status{name:"terminate"})
WHERE (trm)-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(trm) as terminate, quotafull, complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (qal:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_COMPLETE_STATUS]-(:Status{name:"quality"})
WHERE (qal)-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(qal) as quality, terminate, quotafull, complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
// PRESCREENER STATS
OPTIONAL MATCH (pre_cmp:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"complete"})
WITH count(pre_cmp) as prescreener_complete, quality, terminate, quotafull, complete, speeder, returned, reached, avg_loi, total,
s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (pre_qta:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"quotafull"})
WITH count(pre_qta) as prescreener_quotafull, prescreener_complete, quality, terminate, quotafull, complete, speeder, returned,
reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (pre_trm:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"terminate"})
WITH count(pre_trm) as prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull, complete, speeder, returned,
reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
OPTIONAL MATCH (pre_qal:SurveySupUser{survey_id:s.survey_id , env:'live'})-[:HAS_PRE_COMPLETE_STATUS]->(:Status{name:"quality"})
WITH count(pre_qal) as prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull, complete, speeder, returned,
reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client, incomplete
OPTIONAL MATCH (tot_all:SurveySupUser{survey_id:s.survey_id , env:'live'})
WITH COUNT(tot_all) - (prescreener_quality + prescreener_complete + prescreener_terminate + prescreener_quotafull) as prescreener_incomplete, prescreener_quality, prescreener_terminate,
prescreener_quotafull, prescreener_complete, quality, terminate, quotafull, complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
WITH CASE WHEN toInteger(complete) > toInteger(s.total_n) THEN toInteger(complete) - toInteger(s.total_n) ELSE 0 END as oa,
prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client,incomplete
WITH CASE WHEN toInteger(total) > 0 THEN (toFloat(complete) * toFloat(s.cpi)) / toFloat(total) * 100 ELSE 0
END as epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, pman, cy, st, pc, pmode, client, incomplete,
CASE WHEN complete > 0 OR terminate > 0 THEN (toFloat(complete) / toFloat((complete + terminate))) * 100 ELSE 0 END as ir,
CASE WHEN total > 0 THEN (toFloat(complete) / toFloat(total) ) * 100 ELSE 0 END as cr,
CASE WHEN toFloat(reached)>0 THEN toFloat(toFloat(incomplete)/toFloat(reached) *100) ELSE 0 END as br
OPTIONAL MATCH (s)-[:HAS_STATUS]->(pe)
WITH epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
//LANGUAGE
OPTIONAL MATCH (s)-[:USE_LANGUAGE]->(l:Language)
WITH {
language_name: l.language_name,
language_code: l.language_code
} as language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe ORDER BY s.modified_on DESC
//LINKS
OPTIONAL MATCH (s)-[:HAS_SURVEY_LINKS]->(sl:SurveyLinks)
WITH sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
OPTIONAL MATCH (sl)-[:HAS_LINKS]->(lnk:Link)
WITH collect({
link: lnk.link,
is_active: lnk.is_active,
type: lnk.type
}) as links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
//DEVICES
OPTIONAL MATCH (s)-[:HAS_DEVICES]->(dv:Devices)
WITH dv, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
//DEVICE OBJECTS
OPTIONAL MATCH (dv)-[:HAS_DEVICE]->(d:DeviceObject)
WITH d, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe ORDER BY d.device_name ASC
WITH collect({
device_name: d.device_name,
device_code: d.device_code,
is_active: d.is_active
}) as devices, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
//RESTRICTIONS
OPTIONAL MATCH (s)-[:HAS_RESTRICTIONS]->(rs:Restrictions)
WITH rs, devices, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
//RESTRICTION OBJECTS
OPTIONAL MATCH (rs)-[:HAS_RESTRICTION]->(ro:RestrictionObject)
WITH collect({
restriction_name: ro.restriction_name,
restriction_code: ro.restriction_code,
is_active: ro.is_active
}) as restrictions, rs, devices, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe
OPTIONAL MATCH(s)-[:HAS_PROJECT_TYPE]->(pt:ProjectSettingElement)
WITH pt, restrictions, rs, devices, links, sl, language, epc, oa, prescreener_incomplete, prescreener_quality, prescreener_terminate, prescreener_quotafull, prescreener_complete, quality, terminate, quotafull,
complete, speeder, returned, reached, avg_loi, total, s, sp, staff, ir ,pman, cy, st, pc, cr, br, pmode, client,incomplete, pe ORDER BY s.survey_id DESC
RETURN collect({
client_survey: {
quality: quality,
terminate: terminate,
quotafull: quotafull,
complete: complete,
incomplete: incomplete,
total: total,
epc : toString(epc),
oa : oa,
cr : toString(cr) ,
br : toString(br) ,
reached : reached,
returned: returned,
speeder : speeder,
ir : toString(ir) ,
avg_loi : toString(avg_loi),
prescreener_complete : prescreener_complete,
prescreener_quotafull: prescreener_quotafull,
prescreener_terminate: prescreener_terminate,
prescreener_incomplete: prescreener_incomplete,
prescreener_quality : prescreener_quality
},
soft_launch : {
value: s.soft_launch_value,
pc: s.soft_launch_pc,
status: s.soft_launch_status
},
client_reached_traffic_limit: {
value: s.client_reached_traffic_limit_value,
status: s.client_reached_traffic_limit_status
},
epc_traffic_limit : {
value : s.epc_traffic_limit_value,
pc : s.epc_traffic_limit_pc,
status : s.epc_traffic_limit_status
},
links: links,
language: language,
allowed_devices: devices,
restrictions: restrictions,
survey_id: s.survey_id,
survey_name: s.survey_name,
status_id : s.status_id,
status_name : s.status_name,
additional_cost : s.additional_cost,
po_number : s.po_number,
status_color:pe.badge_color,
survey_url_is_multiple: s.survey_url_is_multiple,
tags: s.tags,
total_n: s.total_n,
cpi: s.cpi,
ir: s.ir,
loi: s.loi,
field_days: s.field_days,
survey_cost: s.survey_cost,
start_date: s.start_date,
end_date : s.end_date,
sales_person: sp.name,
sales_person_contact: sp.contact,
sales_person_uid: sp.u_id,
created_by: staff.u_id,
staff_contact: staff.contact,
staff_designation: staff.designation,
staff_uid: staff.u_id,
project_manager: pman.name,
project_manager_contact: pman.contact,
project_manager_designation: pman.designation,
project_manager_uid: pman.u_id,
currency_name: cy.name,
currency_badge_color: cy.badge_color,
currency_id: cy.p_id,
sample_name: st.name,
sample_badge_color: st.badge_color,
sample_id: st.p_id,
category_name: pc.name,
category_badge_color: pc.badge_color,
category_id: pc.p_id,
project_mode : pmode.p_id,
project_type_name : pt.name,
project_type_id: pt.p_id,
client_id:client.client_id,
company_name: client.company_name,
address: client.address,
billing_person: client.billing_person,
billing_email: client.billing_email,
main_contact_name: client.main_contact_name,
main_contact_mobile: client.main_contact_mobile,
main_contact_email: client.main_contact_email }) as survey_list
As a note: SurveySupUser(survey_id) is index and this particular node is having like 50k nodes now.
And the db hits for this query is
Cypher version: CYPHER 4.2, planner: COST, runtime: PIPELINED. 5139002 total db hits in 2630 ms.
Any suggestions will be helpfull