2015-04-13 2 views
0

Я пытаюсь написать запрос, чтобы найти все узлы с полустепенью X и возвращать только пути, которые содержат те узлы, когда длина пути равна Yнайти пути с определенной длиной в сочетании с узлами с определенной степенью Neo4j

Если Я хочу, чтобы получить только узлы с полустепенью XI используйте следующий Cypher-запрос

MATCH (s:URL)-[r:VISITED*]->(t:URL) 
WITH s, count(t) as degreeout 
WHERE 73 in s.job_id and degreeout <4 
return s, degreeout 

Если я хочу, чтобы получить только пути с длиной = XI использовать следующий запрос

MATCH p=(s:URL)-[r:VISITED*]->(t:URL) 
WHERE length(p)=7 
return p 

Я попытался объединить два предыдущих запросов в следующем запросе

MATCH (s:URL)-[r:VISITED*]->(t:URL) 
WITH s, COLLECT(DISTINCT id(s)) as matched, count(t) as degreeout 
WHERE 73 in s.job_id and degreeout <4 
MATCH p=(s2:URL)-[r:VISITED*]-(t2:URL) 
WHERE id(s2) in matched and length(p) >=1 
RETURN p 

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

Кажется, что существует бесконечный цикл!

ответ

1

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

MATCH p=(s:URL)-[r:VISITED*7]->(t:URL) 
return p 

В общем, вы должны избегать делать обходы неограниченной длины, т.е. :VISITED*. Если вы хотите сохранить переменную глубины, потому что она неизвестна, рекомендуется установить максимум. значение, т.е. :VISITED*..7.

Если я правильно понял, исходный запрос может быть настроен, просто установив переменную длину 7 в пути:

MATCH (s:URL)-[r:VISITED*7]->(t:URL) 
WITH s, count(t) as degreeout 
WHERE 73 in s.job_id and degreeout <4 
return s, degreeout 

Вы должны увидеть некоторое улучшение производительности, потому что теперь пути длиной> 7 будет исключены из результатов, и они не пройдут. Опять же, всегда избегайте неограниченных проходов по глубине, если для этого нет веской причины, и у вас достаточно ресурсов компьютера + время для завершения запроса.

Что касается лучших практик производительности, этот запрос все равно не будет работать очень хорошо, поскольку он заставит сканирование графика найти начальный узел. Я понимаю, что узлы с меткой URL содержат свойство job_id типа Array из-за оператора in? Neo4j необходимо прочитать все узлы URL и их свойства, а затем просмотреть эти массивы только для того, чтобы найти начальный узел.

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

(j:Job {job_id: 73})-[:SOMETHING?]->(u:URL {...}) 

Мы также хотели бы добавить индекс схемы:

CREATE INDEX ON :Job(job_id) 

Тогда вы можете запросить так:

MATCH (j:Job {job_id: 73})-[:SOMETHING?]->(s:URL)-[r:VISITED*7]->(t:URL) 
WITH s, count(t) as degreeout 
WHERE degreeout <4 
return s, degreeout 
+0

Я маркировать стартовый узел как STARTING_URL ... так старт узел будет иметь две метки «URL» и «STARTING_URL» –

+0

Что касается job_id, я не могу иметь его как значение свойства int. Я должен иметь его как свойство массива. Я не думаю, что этот способ (j: Job {job_id: 73}) (свойство как словарь) позволит мне обрабатывать атрибут job_id как массив ...! ?? –

+0

Проблема с этим подходом заключается в том, что поиск узла по свойству массива неэффективен, так как он не будет использовать какие-либо индексы, а Neo4j придется сканировать все узлы с соответствующими метками. Если у вас есть n job_ids для каждого STARTING_URL, вы можете создать один узел для каждого job_id и иметь отношение к STARTING_URL, как я пытался объяснить в последнем разделе моего ответа. Этот подход будет использовать больше преимуществ возможностей графического представления Neo4j. – albertoperdomo

Смежные вопросы