2015-01-12 4 views
0

Я новичок в Neo4j, и я получаю удовольствие от некоторых данных о нашей солнечной системе в игре (Elite Dangerous). Как трейдер, вы хотите найти наиболее выгодный маршрут, основанный на определенных критериях. Одним из них является количество прыжков, необходимых между системой и другим. Для того, чтобы посчитать, что сначала нужно вычислить расстояние между всеми системами в 30Ly для каждой системы, так что я придумал этот запрос, чтобы вычислить расстояние в вопросе:Создание многих отношений с вычисленными свойствами

MATCH (s1:System), (s2:System) 
WITH s1, s2, (sqrt((s2.x-s1.x)^2+(s2.y-s1.y)^2+(s2.z-s1.z)^2)) AS dist 
WHERE dist < 30 AND dist > 0 
CREATE UNIQUE (s1)-[:IS_DISTANCED_FROM {distance: dist}]-(s2) 
RETURN count(dist) 

Система по х, у, г координат. Запрос так медленно, даже через час, он не был завершен. Я делаю что-то неправильно?

У меня есть индекс в системе, и я использую версию 2.1.6.

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

Благодарим за помощь!

ответ

0

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

Можете ли вы запустить этот запрос в оболочке neo4j и опубликовать результат Exectution? :

PROFILE MATCH (s1:System) 
WITH s1 
LIMIT 15 
MATCH (s2:System) 
WHERE s2 <> s1 
WITH s1, s2, (sqrt((s2.x-s1.x)^2+(s2.y-s1.y)^2+(s2.z-s1.z)^2)) AS dist 
WHERE dist < 30 AND dist > 0 
CREATE UNIQUE (s1)-[:IS_DISTANCED_FROM {distance: dist}]-(s2) 
RETURN count(dist) 
+0

я выполнил команду (без PROFILE, потому что это не было 'работы) и вот результат: Количество (расстояние) Set 1716 свойства, созданные 1716 отношения, вернулся 1 строку в 4816 мс –

+0

По мой расчет, для всех систем 19800, он должен занять 110 минут в целом, но через 2-3 часа он не завершился :( –

+0

это не сработало, потому что вы не запускали его в оболочке –

0

Неудивительно, что ваш запрос занимает много времени, так как он имеет сложность O (N * N). И индексирование не помогает, так как вы не используете определенные значения свойств.

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

Кроме того, вы можете вдвое увеличить количество вычислений, заметив, что [расстояние от системы A до системы B] равно [расстояние от системы B до системы A]. Вам нужно всего лишь создать единую дистанционную связь между любыми 2 системами.

Наконец, чтобы определить, по-видимому паразитные отношения в вашей БД, вы можете попробовать что-то вроде этого запроса, чтобы взглянуть на некоторые из них:

MATCH()-[r]->() 
RETURN r 
LIMIT 50 

Если вы действительно очень уверены, что вы хотите получить избавившись от отношений ALL, вы можете использовать следующий запрос. Чтобы быть в безопасности, вы можете сначала создать резервную копию своей БД (закрыть сервер БД, сделать рекурсивную копию своей папки data/graph.db/, а затем перезапустить сервер).

MATCH()-[r]->() 
DELETE r 
+0

Благодарим вас за ответ. Когда я использую запрос Cypher, отношений не существует (MATCH() - [r :: IS_DISTANCED_FROM] ->()), но в панели мониторинга neo4j сейчас существует 809 517 отношений ... Я почти уверен, что 600 000 + тех, кто не существует. В любом случае, я могу сбросить кеш базы данных? –

+0

Как создать единую дистанционную связь между двумя системами? Я думал, что CREATE UNIQUE служил этой цели? –

+0

Вы не должны подбирать свой запрос с типом отношений. То есть, используйте '[r]' вместо '[r: IS_DISTANCED_FROM]'. У вашей БД, видимо, есть много отношений другого типа (ов). – cybersam

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