2016-05-21 4 views
1

Я делаю «друг друга» в MATCH в Neo4j. Единственное, что меня выбрасывает, это попытка ограничить все отношения по дате.Матч FOAF, но ограничение пути по дате; определенно последовательно, в Neo4j

Основной график следующим образом:

enter image description here

«реальный» версия графа имеет 10 1-й степени друзей и 3385 2-й степени друзей.

И хотя я не помещал свойство даты на каждом ребре на изображении выше, действительно, это так. Нет ни одного заказа на какие-либо даты.

Общая идея довольно проста: я хотел бы не обращать внимания на любые отношения, у которых есть свойство даты, которое превышает установленную максимальную дату.

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

Я написал:

MATCH 
(n)-[f1:FRIEND]-()-[f2:FRIEND]-(m) 
WITH n, m,split('1962-1-1', '-') AS maxdate 
WHERE n.person_id='180' 
AND(
(
toInt(maxdate[0]) > toInt(split(f1.date, '-')[0]) 
) 
OR 
(
toInt(maxdate[0]) = toInt(split(f1.date, '-')[0]) 
AND 
toInt(maxdate[1]) >= toInt(split(f1.date, '-')[1]) 
)) 
AND(
(
toInt(maxdate[0]) > toInt(split(f2.date, '-')[0]) 
) 
OR 
(
toInt(maxdate[0]) = toInt(split(f2.date, '-')[0]) 
AND 
toInt(maxdate[1]) >= toInt(split(f2.date, '-')[1]) 
)) 
RETURN m; 

Этот блок кода побежал в течение приблизительно 20 минут, и в конце концов, по-видимому, в результате чего-то близко к тому, что я стремился. Вот как это выглядит в браузере:

enter image description here

(Он имеет 350 узлов)

во-первых, я признаю, что это очевидно, что некоторые ужасно написанный код (как с точки зрения эстетики и производительности). Во-вторых, я замечаю непривязанные узлы по периметру.

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

Как изменить мое условие даты, чтобы исключить эти отдельно стоящие узлы, когда край первой степени недействителен?

Если у кого-нибудь есть понимание, я был бы очень признателен. (Не слишком мягко, но благодаря сообществу SO, я уже довольно далеко продвинулся довольно быстро, и за это я благодарен.)

ответ

2

Это не должно длиться так долго, в первую очередь, Основная причина в том, что у вас нет метки + индекс на ваших узлах.

addd тех первых:

CREATE CONSTRAINT ON (p:Person) ASSERT p.person_id is unique; 
MATCH (n) where exists(n.person_id) SET n:Person; 

, если у вас есть время в yyyy-mm-dd так или иначе (я надеюсь на это, по крайней мере), вы можете сравнить их непосредственно: (с 2-мя цифрами ака 01) т.е.'2012-01-10' > '2011-08-31')

WITH '1962-01-01' AS maxdate 
MATCH (n:Person)-[f1:FRIEND]-()-[f2:FRIEND]-(m:Person) 
WHERE n.person_id='180' AND f1.date < maxdate and f2.date < maxdate 
RETURN m; 

вы также можете использовать короткую форму: (n:Person {person_id:'180'})

, если вы хотите иметь общее выражение отношений в пути, используйте переменную rels (который затем коллекция) в вашем шаблон переменной длины пути:

WITH '1962-01-01' AS maxdate 
MATCH (n:Person {person_id:'180'})-[rels:FRIEND*2]-(m:Person) 
WHERE ALL(r in rels WHERE r.date < maxdate) 
RETURN m; 

вы также можете использовать rels(path)

WITH '1962-01-01' AS maxdate 
MATCH path = (n:Person {person_id:'180'})-[:FRIEND*2]-(m:Person) 
WHERE ALL(r in rels(path) WHERE r.date < maxdate) 
RETURN m; 

или если отношения путей являются по отношению друг к другу:

WITH '1962-01-01' AS maxdate 
MATCH (n:Person {person_id:'180'})-[rels:FRIEND*2]-(m:Person) 
WHERE ALL(idx in range(0, size(rels)-2) WHERE (rels[idx]).date < maxdate AND (rels[idx]).date < (rels[idx+1]).date) 
RETURN m; 
+0

Я все еще получаю эти странные, изолированные и отключенные узлы по периметру ... необходимость дальнейшего изучения (а вдруг я понимаю, это 4:45!) –

+1

, что всегда бывает :) (время, которое я имею в виду) Я исправил синтаксис в последнем (пропустил скобку) –

+0

Есть ли какой-либо рейтинг этих запросов с точки зрения производительности? –