2015-11-16 3 views
1

Я хотел бы перебрать все узлы в ~ 100Mio-графе. Я знаю, что может получить узлы с шифровальщика запросомвстроенный neo4j: итерация по всем узлам огромного графика

MATCH n RETURN n 

, но тогда я должен был бы использовать LIMIT и SKIP работать сам по набору данных, и я думаю, что есть производительность вопросы, связанные с этим подходом.

Теперь мой вопрос: как я могу перебирать все узлы с помощью встроенной базы данных neo4j? Все это будет фоновая работа (индексирование узлов до elasticsearch).

ответ

4

Спасибо, ребята, за то, что упомянул GraphAware, просто чтобы добавить другой подход в микс: проблема с получением всех узлов с ванилью GlobalGraphOperations заключается в том, что все это происходит в одной транзакции. На графике с узлами 100M это не сработает.

По этой причине GraphAware Framework имеет ряд BatchTransactionExecutor с, что мы используем в наших модулей для повторной индексации/восстановления и такие сценарии, когда вам нужно сделать что-то для каждого узла/отношения или подмножество из них.

Позвольте мне опубликовать пример того, как вы будете использовать это - это из модуля схемы Enforcement GraphAware (а не с открытым исходным кодом, поэтому размещение здесь):

final List<String> violations = new LinkedList<>(); 

    new IterableInputBatchTransactionExecutor<>(database, 1000, 
      new AllNodes(database, 1000), 
      new UnitOfWork<Node>() { 
       @Override 
       public void execute(GraphDatabaseService database, Node input, int batchNumber, int stepNumber) { 
        for (Constraint<Node> constraint : nodeConstraints) { 
         if (!constraint.satisfiedBy(input)) { 
          violations.add(input + " violates " + constraint.toString()); 
         } 
        } 
       } 
      }).execute(); 

Большинство входных параметров должны быть понятны. Обратите внимание, что AllNodes - это другой класс рамок, который извлекает все узлы из database партиями 1000 (в данном случае) за транзакцию. Мы предоставляем другие (AllNodesWithLabel, AllRelationships), но вы можете легко реализовать свои собственные.

Выполнение этого в фоновом режиме - это вопрос создания отдельного потока, или если вы хотите получить более сложный подход, используйте модули с таймером фреймворка, как уже указывал Уильям.

3

Поскольку вы упоминаете, что используете встроенный Neo4j, вы можете использовать API Java, как описано в документе here вместо Cypher.

В частности, класс GlobalGraphOperations предоставляет метод getAllNodes() как документально here:

for (Node node : GlobalGraphOperations.at(db).getAllNodes()) { 
    // Do something with the node here 
} 

Редактировать

несколько других точек рассмотреть:

  1. Вы могли бы реализовать transaction hook handler к инициировать операцию индексирования Elasticsearch, когда узел вставляется/обновляется, а не итерируется через все узлы в базе данных.
  2. Если вы хотите, чтобы эта операция выполнялась периодически в фоновом режиме, вам может потребоваться использовать GraphAware framework's таймер, приводимый в действие runtime module. Этот плагин предоставляет время выполнения для выполнения операций периодически в фоновом режиме и может быть настроен на масштабирование при увеличении загрузки базы данных.
+2

Отметим также, что GraphAware уже имеет модуль для репликации ES: https://github.com/graphaware/neo4j-to-elasticsearch –

+0

Вы можете просто выполнить обработку узлов, которые вы возвращаете из getAllNodes(), с несколькими потоками в бассейне, тогда это действительно эффективно. –

Смежные вопросы