2011-12-12 12 views
9

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

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

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

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

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

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

A knows B 
A knows B 
A knows B 

означает соотношение прочности 3.

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

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

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

ответ

5

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

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

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

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

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

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 

что бы «приращение» означает, в не целочисленном случае?

+0

Спасибо - несколько интересных возможностей! После проверки словаря, я думаю, что это нормально говорить о нецелочисленных «приращениях» (хотя, очевидно, вам нужно будет указать сумму)! – DNA

1

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

+0

На грубом предположении я бы сказал несколько десятков миллионов узлов. Количество отношений менее определенно, но, вероятно, небольшое число узлов. График будет постоянно обновляться, добавляя или обновляя десятки или несколько сотен объектов в секунду. Нагрузка считывания, вероятно, будет довольно легкой; выбор небольшого числа узлов в локальности указанного узла, например. – DNA

+0

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

2

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

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