Объединение Neo4J и MongoDB: согласованность

В последнее время я много экспериментирую, и одна из вещей, которые я хотел сделать, — это объединить две популярные базы данных NoSQL, а именно Neo4j и MongoDB. Просто потому, что я чувствую, что они идеально дополняют друг друга. Граждане первого класса в Neo4j, отношения, — это именно то, чего не хватает в MongoDB, тогда как MongoDb позволяет мне не помещать большие объемы данных в свойства моего узла.

Поэтому я пытаюсь объединить их в приложении Java, используя привязку Neo4j Java REST и драйвер Java MongoDB. Все объекты моего домена имеют уникальный идентификатор, который я храню в обеих базах данных. Остальные данные хранятся в MongoDB, а отношения между сущностями хранятся в Neo4J. Например, обе базы данных содержат идентификатор пользователя, MongoDB содержит информацию о профиле, а Neo4J содержит сведения о дружеских отношениях. С пользовательским уровнем доступа к данным, который я написал, это работает именно так, как я хочу. И это быстро.

НО... Когда я хочу создать пользователя, мне нужно создать и узел в Neo4j, и документ в MongoDB. Не обязательно проблема, за исключением того, что Neo4j является транзакционным, а MongoDB — нет. Если бы обе транзакции были транзакционными, я бы просто откатывал обе транзакции, когда одна из них терпит неудачу. Но поскольку MongoDB не является транзакционной, я не могу этого сделать.

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

Кроме того, я не только хочу, чтобы мое комбинированное взаимодействие с базой данных было совместимым с ACID, я также хочу, чтобы оно было потокобезопасным. И GraphDatabaseService, и MongoClient/DB предоставляются из синглетонов.

Я нашел кое-что о создании «Документов транзакций» в MongoDB, но мне действительно не нравится этот подход. Я хотел бы что-то красивое и чистое, например настройку neo4j beginTx, tx.success, tx.failure, tx.finish. В идеале что-то, что я могу реализовать в том же блоке try/catch/finally.

Должен ли я, возможно, переключиться на CouchDB, который, похоже, является транзакционным?

Редактировать: После дополнительных исследований, вызванных комментариями, я пришел к выводу, что CouchDB также не подходит для моих конкретных нужд. Чтобы уточнить, часть Neo4j высечена в камне. База данных хранилища документов не так длинна, как в ней есть библиотека Java.


person Pieter-Jan    schedule 07.05.2013    source источник
comment
Где вы видите транзакции в CouchDb? MongoDB не имеет транзакций (по дизайну). Похоже, вам нужны не только транзакции, но, возможно, и распределенные транзакции. Вам нужно использовать БД с транзакциями или создать процесс, который очищает устаревшие/отключенные данные.   -  person WiredPrairie    schedule 07.05.2013
comment
Виноват. Я не был хорошо информирован. Я немного читал о Couch DB, но из кусочков информации я ошибочно сделал вывод, что у них были ACID-транзакции. И да, я ищу распределенные транзакции.   -  person Pieter-Jan    schedule 07.05.2013


Ответы (3)


Питер-Ян,

если вы можете использовать Neo4j 2.0, вы можете реализовать Schema-Index-Provider (что очень просто), который создает ваши документы транзакционно в MongoDB.

Так как Neo4j делает своих провайдеров индексов транзакционными (с самого начала), мы сделали это с Lucene, а также для Redis (нужно обновить). Но с Neo4j 2.0 все гораздо проще, если хотите, можете посмотреть мою реализацию для MapDB. (https://github.com/jexp/neo4j-mapdb-index)

person Michael Hunger    schedule 07.05.2013
comment
Хороший! Почти чувствую себя виноватым за то, что предложил другую технологию. ;-) - person tstorms; 07.05.2013
comment
КЛАССНО! Вот почему мне так нравится Neo4j. Когда вы не можете найти это в документации, всегда найдется какой-нибудь умный чувак, у которого есть решение. Огромное спасибо! - person Pieter-Jan; 07.05.2013
comment
Итак, я работаю над этим, и я просто хочу проверить, иду ли я в правильном направлении с этим. Вместо фактического индексирования узла я просто удостоверяюсь, что всякий раз, когда узел индексируется, на самом деле происходит создание документа в коллекции. Я также применил уникальность, чтобы у вас не могло быть двух документов для одного узла. Теперь, чтобы добавить информацию в эти документы, я могу просто использовать запрос Mongo, чтобы найти документ и отредактировать его, верно? - person Pieter-Jan; 08.05.2013
comment
@Pieter-Jan Питер-Ян Вы нашли или написали поставщик индексов для MongoDB? - person Gal Ben-Haim; 12.03.2014
comment
Мне нужно реализовать то же самое в моем приложении. Поделитесь, как вы это сделали? - person Abhimanyu; 04.02.2015

Хотя я большой поклонник обеих технологий, я думаю, что лучшим вариантом для вас может быть OrientDB. Это база данных графа (как Neo4) и документа (как MongoDB) в одном и поддерживает транзакции ACID. Звучит как идеальное совпадение для ваших нужд.

person tstorms    schedule 07.05.2013
comment
Боюсь, что часть Neo4j высечена в камне по разным причинам, в том числе и за пределами моей юрисдикции. Но у меня также есть некоторые сомнения по поводу OrientDB. Кажется, они стараются быть хорошими во всем. И, к сожалению, мне еще предстоит найти продукт, который попробовал бы это и преуспел. Я могу ошибаться здесь, но почему-то я сомневаюсь, что OrientDB может предоставить продукт, который может конкурировать с лучшими студентами как в классе Graph DB, так и в классе Document Store. Но, конечно, это может быть просто мой цинизм... И, как и вы, я тоже в некотором роде фанат :D - person Pieter-Jan; 07.05.2013

Как опубликовано здесь https://stackoverflow.com/questions/23465663/what-is-the-best-practice-to-combine-neo4j-and-mongodb?lq=1, вы можете взглянуть на Structr.

Его бэкэнд можно рассматривать как базу данных документов вокруг Neo4j. Он полностью транзакционный и с открытым исходным кодом.

person Axel Morgner    schedule 05.05.2014