Представление (и увеличение) силы отношений в Neo4j - PullRequest
9 голосов
/ 12 декабря 2011

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

Для статического графика это легко сделать, установив свойство «сила» для отношения:

  A --knows--> B
       |
     strength
       |
       3

Однако для графика, который требует обновления с течением времени, существует проблема, поскольку увеличение значения свойства не может быть выполнено атомарно (через интерфейс REST), так как чтение до написать обязательно. Увеличение (а не просто обновление) необходимо, если график обновляется в ответ на входящие потоковые данные.

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

Еще одним решением может быть запись нескольких отношений без каких-либо свойств, так что «сила» - это фактически количество отношений, т. Е.

A knows B
A knows B
A knows B

означает отношение силы 3.

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

Кто-нибудь пробовал этот подход и может ли он столкнуться с проблемами производительности, особенно при чтении?

Есть ли лучший способ смоделировать это?

Ответы [ 3 ]

5 голосов
/ 13 декабря 2011

Хорошая идея.Чтобы уменьшить объем хранилища и многократного чтения, эти отношения можно объединить в одно в пакетном задании, которое выполняется транзакционно.

Каждый rel также может иметь индивидуальное значение веса, агрегированное значение которого используется в качестве веса.Он не обязательно должен быть целочисленным, а также может быть отрицательным для представления декрементов.

Вы также можете написать небольшое расширение сервера для обновления значения веса для одного отношения транзакционно.Возможно, даже имеет смысл для REST API (поскольку в дополнение к операции «установить одно значение» есть операция изменения одного значения.

PUT http://localhost:7474/db/data/node/15/properties/mod/foo 

Тело содержит дельта-значение (1,5, -10). ДругоеИдея состояла бы в том, чтобы заменить ключевое слово mode фактической операцией.

PUT http://localhost:7474/db/data/node/15/properties/add/foo 
PUT http://localhost:7474/db/data/node/15/properties/or/foo 
PUT http://localhost:7474/db/data/node/15/properties/concat/foo 

Что будет означать "приращение" в нецелом регистре?

2 голосов
/ 23 декабря 2011

Хм, немного другой подход, но вы могли бы рассмотреть возможность использования системы очередей. Я также использую интерфейс REST Neo4j и пытаюсь сохранить постоянно меняющиеся отношения. Проект находится в Rails и использует Resque. Всякий раз, когда требуется обновление базы данных Neo4j, оно добавляется в очередь Resque для завершения работником. У меня только один работник работает над очередью Neo4j Resque, поэтому он никогда не пытается выполнить более одного обновления Neo4j одновременно.

Это дает дополнительное преимущество, заключающееся в том, что пользователь не ждет обновлений neo4j при выполнении действия, которое запускает обновление. Однако это жизнеспособное решение, только если вам не нужно мгновенно использовать / отображать обновления Neo4j (хотя в зависимости от скорости вашего работника и размера вашей очереди это может занять всего несколько секунд).

1 голос
/ 13 декабря 2011

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

...