Это запрос, который я пытаюсь запустить в neo4j, но он занимает слишком много времени: - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь выполнить этот запрос с использованием Neo4j, но он выполняется слишком долго (более 30 минут, для почти 2500 узлов и 1,8 миллиона отношений):

Match (a:Art)-[r1]->(b:Art)  
with collect({start:a.url,end:b.url,score:r1.ed_sc}) as row1

MATCH (a:Art)-[r1]->(b:Art)-[r2]->(c:Art)

Where a.url<>c.url
with row1 + collect({start:a.url,end:c.url,score:r1.ed_sc*r2.ed_sc}) as row2

Match (a:Art)-[r1]->(b:Art)-[r2]->(c:Art)-[r3]->(d:Art)

WHERE a.url<>c.url and b.url<>d.url and a.url<>d.url


with row2+collect({start:a.url,end:d.url,score:r1.ed_sc*r2.ed_sc*r3.ed_sc}) as allRows

unwind allRows as row

RETURN row.start as start ,row.end as end , sum(row.score) as final_score limit 10;

Здесь :Art - этометка, под которой находится 2500 узлов, и между этими узлами существуют двунаправленные отношения, свойство которых называется ed_sc.Поэтому в основном я пытаюсь найти оценку между двумя узлами путем обхода путей на одну, две и три градуса, а затем суммировать эти оценки.

Есть ли более оптимизированный способ сделать это?

1 Ответ

0 голосов
/ 05 июня 2018

Для одного я бы не рекомендовал использовать двунаправленные отношения.Если ваш график плотно связан, то этот тип моделирования будет разрушать большинство запросов, подобных этому.

Предполагая, что url уникален для каждого узла Art: было бы лучше сравнить сами узлы, а не ихproperties.

Мы также должны иметь возможность использовать отношения переменной длины вместо вашего текущего подхода:

MATCH p = (start:Art)-[*..3]->(end:Art)  
WHERE all(node in nodes(p) WHERE single(t in nodes(p) where node = t))
WITH start, end, reduce(score = 1, rel in relationships(p) | score * rel.ed_sc) as score
WITH start, end, sum(score) as final_score
LIMIT 10
RETURN start.url as start, end.url as end, final_score
...