2016-06-03 2 views
1

Я использую Neo4j для хранения данных приложения и ниже изображения изображает структуру графаNeo4j Шифр ​​запрос работает очень медленно

graph

Каждого кругом является узлом, а каждая стрелка изображает зависимость и тип отношений определен выше , Он также определяет many to many or one to many or one to one relationship for nodes.

Что я хотел бы получить с графика.

Я хочу, чтобы перечислить все позиции для компании, и каждая позиция будет иметь множество пользователей, и каждый пользователь будет иметь массив обратной связи для каждого интервью раунда, как показано ниже

position ---> candidate1 interview round name (Telephonic) question1 answer1 and answer given by user1 question1 answer1 and answer given by user2 interview round name (HR Round) question1 answer1 and answer given by user1 question1 answer1 and answer given by user2 candidate2 interview round name (Telephonic) question1 answer1 and answer given by user1 question1 answer1 and answer given by user2 interview round name (HR Round) question1 answer1 and answer given by user1 question1 answer1 and answer given by user2 . . .

Много кандидатов не будут иметь раундов интервью, чем для тех кандидатов, раунды должны быть нулевыми.

Ниже приведен запрос, который я использую для получения необходимых данных.

MATCH (comp:Company {dId: "155dyv1wgT"})<-[:`POSITION_COMPANY`]-(pos: Position {status: 'OPEN'})-[:`POSITION_WORKFLOW`]->(:WorkFlow)-[:`WORKFLOW_CANDIDATE-WORKFLOW`]->(cw : CandidateWorkFlow)-[:`CANDIDATE-WORKFLOW_COMPANY-CANDIDATE`]->(cc : CompanyCandidate) 

where ((not (has(cc.isSpam) or has(cc.isTrash))) OR (cc.isSpam=false and cc.isTrash=false)) and pos.positionType IN ['PUBLIC','DISCRETE'] with distinct comp, {dId: pos.dId, title: pos.title} as pos, cw, cc 

OPTIONAL MATCH (cw)-[:`CANDIDATE_WORKFLOW_INTERVIEW`]->(inwrkflw: InterviewWorkFlow)-[:`INTERVIEW_ROUND`]->(intrnd: InterviewRound)-[:`INTERVIEW_ROUND_FEEDBACK`]->(ffform: FeedbackForm)-[:`FEEDBACK_QUESTION`]-(ffq: Question) 

OPTIONAL MATCH (inwrkflw)-[:`INTERVIEW_WORKFLOW_FEEDBACK`]-(ff:Feedback) 

OPTIONAL MATCH (iwr : User)-[:`FEEDBACK_BY`]->(ff)-[:`FEEDBACK_ANSWER`]->(answer:Answer)-[:`QUESTION_ANSWER`]->(ffq) 

with collect({answer : answer.value, rating: answer.rating, question : ffq.qText, givenBy : iwr.fullName, type: ffq.questionType, givenOn: answer.lastModifiedDate}) as rnds, cc, pos, intrnd 

with filter(rnd IN rnds WHERE rnd.type = 'COMMENTS') as comments, filter(rnd IN rnds WHERE rnd.type = 'LINEAR_GENERIC') as ratings, cc, pos, intrnd 

with distinct collect({roundName: intrnd.name, ratings: ratings, comments: comments}) as rounds, cc, pos 

return collect({cc: cc, rounds: rounds}) as data, pos.dId as posId, pos.title as posTitle 

dId уникален на каждом узле.

Проблема с этим запросом заключается в небольшом наборе данных, скажем, 1000 кандидатов с 10 позициями, которые будут работать нормально. Но для больших наборов данных это занимает слишком много времени, чтобы возвращать результаты. Я даже дождался 5 минут в консоли neo4j для ответа, но ответа не было за 5 минут.

Приложение не будет иметь 1000 кандидатов. Количество кандидатов будет доходить до 100000 за наименьшее и максимальное количество, которое я могу считать равным 1 миллиону за компанию.

Я пробовал различный способ оптимизировать этот запрос, но не смог получить ответ.

Ответ SLA должен находиться в пределах 20 секунд.

Мои вопросы

  1. Как можно оптимизировать этот запрос, чтобы получить результаты, которые я хочу?
  2. Что не так в текущем запросе?
+1

вы можете запустить свой запрос с профильными и поделиться результатом? –

+0

Вы можете поделиться своей базой данных со мной? michael at neo4j.com –

+0

какая версия вы используете? –

ответ

0

Сначала я обновил ваш дБ до 2.3.3

Ваша модель состоит из двух подграфов, которые описывают

  1. мета-информации о процессе приема на работу
  2. конкретные отзывы/ответы на одного кандидата

Для вашей компании и довольно большой:

  1. 235600 пути от компании к вопросу через процесс собеседования
  2. 83937 от компании на вопрос через конкретные ответы

каждый из которых занимает около 1 секунды, чтобы вычислить

Если вы только запрос через них, вы перемножить числа, которые заканчивается до 20 миллиардов путей ,

, который занимает довольно навсегда вычислить

Мое решение было запросить один подграф первым, а затем положить его в сторону (в совокупности), а затем запросить второй подграф

Во-первых, я привел их вместе согласующие ответы на вопросы (включена в операцию ExpandInto)

WHERE (answer)-[:QUESTION_ANSWER]->(ffq)

который сделал отделку запросов примерно 15 секунд.

Тогда я продлила бетон (ответ) подграф один шаг на вопросы и свел их на сам вопрос (ffq = ffq2)

Таким образом, общее время выполнения до 1,6 секунды.

Вот окончательный запрос:

MATCH (comp:Company {dId: "155dyv1wgT"})<-[:`POSITION_COMPANY`]-(pos: Position {status: 'OPEN'})-[:`POSITION_WORKFLOW`]->(:WorkFlow)-[:`WORKFLOW_CANDIDATE-WORKFLOW`]->(cw : CandidateWorkFlow)-[:`CANDIDATE-WORKFLOW_COMPANY-CANDIDATE`]->(cc : CompanyCandidate) 

where ((not (has(cc.isSpam) or has(cc.isTrash))) OR (cc.isSpam=false and cc.isTrash=false)) and pos.positionType IN ['PUBLIC','DISCRETE'] with distinct comp, {dId: pos.dId, title: pos.title} as pos, cw, cc 

with distinct comp, {dId: pos.dId, title: pos.title} as pos, cw, cc 

MATCH (cw)-[:`CANDIDATE_WORKFLOW_INTERVIEW`]->(inwrkflw) 

MATCH (inwrkflw)-[:`INTERVIEW_ROUND`]->(intrnd)-[:`INTERVIEW_ROUND_FEEDBACK`]->(ffform)-[:`FEEDBACK_QUESTION`]-(ffq) 

WITH comp,pos, cw, cc,inwrkflw, collect({round:intrnd,form:ffform,question:ffq}) as workflow_questions 

MATCH (inwrkflw)-[:`INTERVIEW_WORKFLOW_FEEDBACK`]-(ff:Feedback) 
MATCH (iwr : User)-[:`FEEDBACK_BY`]->(ff)-[:`FEEDBACK_ANSWER`]->(answer:Answer)-[:`QUESTION_ANSWER`]->(ffq2) 

UNWIND workflow_questions as wq 

WITH comp,pos, cw, cc,inwrkflw, iwr,ff,answer, wq.round as intrnd, wq.form as ffform, wq.question as ffq 

WHERE ffq2 = ffq 

with collect({answer : answer.value, rating: answer.rating, question : ffq.qText, givenBy : iwr.fullName, type: ffq.questionType, givenOn: answer.lastModifiedDate}) as rnds, cc, pos, intrnd 

with filter(rnd IN rnds WHERE rnd.type = 'COMMENTS') as comments, filter(rnd IN rnds WHERE rnd.type = 'LINEAR_GENERIC') as ratings, cc, pos, intrnd 

with collect({roundName: intrnd.name, ratings: ratings, comments: comments}) as rounds, cc, pos 

return collect({cc: cc, rounds: rounds}) as data, pos.dId as posId, pos.title as posTitle; 
Смежные вопросы