Как перебрать свойства для сравнения для определенного типа узла в Neo4j, используя Cypher - PullRequest
0 голосов
/ 26 сентября 2019

Я использую Neo4j и задаюсь вопросом, как использовать Cypher для циклического просмотра свойств других узлов, соединяющих один узел для сравнения, и фильтрации тех, которые удовлетворяют условию.

Вот пример данных:

Person Movie Publish_Date
Tina   A     2016-01-01
Tina   B     2016-01-01
Tina   C     2016-03-05
Tina   D     2016-03-06
Tina   X     2018-03-09  
Bob    E     2016-08-01
Bob    F     2016-08-08
Ana    G     2016-04-05
Ana    H     2016-08-05
Ana    I     2016-12-05

Вот что я хочу:

Person Movie Publish_Date
Tina   A     2016-01-01
Tina   B     2016-01-01
Tina   C     2016-03-05
Tina   D     2016-03-06
Tina   X     2018-03-09   
Bob    E     2016-08-01
Bob    F     2016-08-08

Я хочу вернуть человека, который участвовал в более чем 2 фильмах, опубликованных за 30 дней, и информацию о фильме.

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

Вот мой запрос для получения образцов данных:

MATCH (p:Person)-[r1:ACTED_IN]->(m:Movie)
WITH p, m 
ORDER BY p.Name DESC, n.Publish_Date
RETURN p.name AS Person, m.title AS Movie, m.publish_date AS Publish_Date

Пожалуйста, предложите.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

Этот запрос покажет вам, есть ли между двумя фильмами одного и того же человека интервал менее 30 дней.Оттуда вы можете фильтровать, как вы хотите:

MATCH (m1:Movie)<-[:ACTED_IN]-(p:Person)-[:ACTED_IN]->(m2:Movie) 
WITH p, m1,m2, datetime(m1.Publish_Date) as date1, datetime(m2.Publish_Date) as date2
return p.name,m1.title,m2.title,
CASE WHEN date1<date2
THEN date1+duration("P30D")>date2
ELSE date2+duration("P30D")>date1 END AS lessThan30DaysApart
0 голосов
/ 27 сентября 2019

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

Я предполагаю, что вы ищете на человекаПо крайней мере один набор из 2 фильмов, которые были опубликованы в течение 30 дней друг от друга (в противном случае вы не ожидали бы записей Боба в своих результатах).

Я также предполагаю, что вы хотели, чтобы фильм X опубликовалбыть 2016-03-09 вместо 2018-03-09 в противном случае это не должно быть в ожидаемых результатах.

С этими допущениями, этот запрос должен выполнить трюк:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH p, m 
ORDER BY m.publish_date
WITH p, collect(m) as movies, collect(m.publish_date) as dates
UNWIND range(0, size(movies)-2) as index
WITH p, movies, dates, index 
WHERE duration.inDays(dates[index], dates[index+1]).days <= 30
UNWIND [movies[index], movies[index+1]] as movieInRange
RETURN DISTINCT p, movieInRange
ORDER BY p.name DESC

Мы UNWIND диапазон отОт 0 до 2 меньше, чем размер списка фильмов на человека, чтобы мы могли выполнить индексацию в списках (мы будем оценивать даты фильмов в парах, чтобы мы могли провести сравнение).

Для смежных пар, опубликованных в течение 30 дней друг от друга, мы УВЕЛИЧИВАЕМ коллекцию смежных фильмов, чтобы оба фильма находились под одной и той же переменной, затем мы возвращаем отсортированные значения DISTINCT (поскольку один и тот же фильм можетпроисходят дважды, в течение 30 дней после фильма до и после.

...