Как обрабатывать даты в neo4j
Я историк средневековой истории, и я пытаюсь кодировать сети между королями, герцогами, пап и т.д. в течение периода времени около 50 лет (с 1220 по 1270 год) в средневековой Германии. Поскольку я не специалист по графическим базам данных, я ищу возможность обрабатывать даты и диапазоны дат.
Существуют ли какие-либо возможности для обработки диапазона дат до края, чтобы края, представляющие отношения, исчезали после, например, 3 года?
Есть ли возможность запросить отношения, у которых есть метка даты в диапазоне дат?
Ответы
Ответ 1
Общим способом обработки дат в Neo4j является их сохранение либо в виде строкового представления, либо как миллисекунда с эпохи (aka msec, прошедшего с 01 января 1970 года).
Первый подход делает граф более легко читаемым, последний позволяет выполнять математику, например, вычислять дельта.
В вашем случае я бы сохранил два свойства, называемые validFrom
и validTo
в отношениях. Вы должны убедиться, что ищете правильный интервал времени.
например. чтобы найти короля (ов), отвечающего за Францию с 01 января 1220 по 31 декабря 1221 года, вы:
MATCH (c:Country{name:'France'})-[r:HAS_KING]->(king)
WHERE r.validFrom >= -23667123600000 and r.validTo <=-23604051600000
RETURN king, r.validFrom, r.validTo
добавление
Так как Neo4j 3.0 есть библиотека APOC, которая предоставляет пару функций для преобразования временных меток в/из строк, читаемых пользователем.
Ответ 2
Вы также можете сохранить даты в их числовом представлении в следующем формате: YYYYMMDD
В вашем случае 12200101
будет 1 января 1221 года, а 12701231
- 31 декабря 1270 года.
Это полезный и читаемый формат, и вы можете выполнять поиск по диапазону, например:
MATCH (h:HistoricEvent)
WHERE h.date >= 12200101 AND h.date < 12701231
RETURN h
Он также позволит вам заказывать по датам, если вам нужно.
Ответ 3
Другим вариантом для дат, который поддерживает количество узлов/свойств, которые вы создаете довольно низко, является связанный список лет (самый ранний год интереса - последний год), один из месяцев (1-12) и один из дат в месяц (1-31). Затем каждое "событие" на вашем графике может быть подключено к году, месяцу и дню. Таким образом, вам не нужно создавать новый node для каждой новой комбинации года и дня. У вас всего один месяц, один день и один год. Я масштабирую числа, чтобы облегчить им манипулирование.
Годы yyyy * 10000
Месяцы - мм * 100
Дата dd
поэтому, если вы запустите запрос, например
match (event)-[:happened]->(t:time)
with event,sum(t.num) as date
return event.name,date
order by date
Вы получите список всех событий в хронологическом порядке с такими датами, как Janurary 17th, 1904, появляющийся как 19040117 (формат yyyymmdd)
Далее, поскольку они связаны списками, где, например, ...- (t0: time {num: 19040000}) - [: предшествует] → (t1: время {num: 19050000}) -...
упорядочение также встроено в узлы.
Это до сих пор, как мне нравилось делать свое мероприятие знакомства