Статьи

Гибкий пакетный импорт Neo4j с Groovy

У вас могут быть данные в виде файлов CSV для создания узлов и связей в вашей базе данных графиков Neo4j .

Это может быть много данных, например, десятки миллионов строк.

Слишком много для LOAD CSV для обработки транзакций.

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

Ваши требования

Есть некоторые вещи, которые вы, вероятно, хотите сделать иначе, чем пакетный импортер делает по умолчанию:

  • не создавать устаревшие индексы

  • не индексировать свойства вообще, что вам просто нужно для подключения данных

  • создать индексы схемы

  • пропустить определенные столбцы

  • переименовать свойства из имен столбцов

  • создавать свои собственные метки на основе данных в строке

  • преобразовать значения столбцов в типы Neo4j (например, разделенные строки или анализ JSON)

API Batch Inserter

Здесь вы, даже не являясь Java-разработчиком, можете написать несколько строк кода и сделать это.
API Batch-Inserter Neo4j быстрые и простые, вы можете продвинуться далеко вперед с помощью всего лишь нескольких основных методов

  • insertter.createNode (свойства, метки) → идентификатор узла

  • insertter.createRelationship (fromId, toId, тип, свойства) → rel-id

  • inserter.createDeferredSchemaIndex (ярлык) .он (собственность) .create ()

Демо-данные

Для нашей демонстрации мы хотим импортировать статьи, авторов и цитаты из базы данных цитирования MS. // сделать

Файл выглядит так:

автор заглавие Дата

Максимум

Спички

2012-01-01

отметка

Clojure

2013-05-21

Майкл

леса

2014-02-03

Настройка с помощью Groovy

Чтобы свести к минимуму «Java» этого упражнения, я выбрал groovy динамический язык JVM, который ближе к ruby ​​и javascript, чем к Java.
Вы можете запускать программы на Groovy как сценарии, как на других языках сценариев.
И что еще более важно, он поставляется с классной функцией, которая позволяет нам запускать все это без настройки и сборки конфигурации или установки зависимостей вручную.

Если вы хотите, вы можете сделать то же самое в jRuby, Jython или JavaScript (Rhino на Java7, Nashorn на Java8) или Lisp (Clojure).
Хотелось бы получить вариант программы на этих языках.

Убедитесь, что у вас установлены Java Development Kit (JDK) и Groovy .

Нам нужны две зависимости: читатель CSV (GroovyCSV) и Neo4j, и мы можем просто объявить их с аннотацией @Grab и импортировать классы в область видимости. (Спасибо Стефану за подсказку.)

@Grab('com.xlson.groovycsv:groovycsv:1.0')
@Grab('org.neo4j:neo4j:2.1.4')
import static com.xlson.groovycsv.CsvParser.parseCsv
import org.neo4j.graphdb.*

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

Чтение CSV — это простая однострочная строка, вот быстрый пример, более подробную информацию о универсальной конфигурации в.

csv = new File("articles.csv").newReader()
for (line in parseCsv(csv)) {
   println "Author: $line.author, Title: $line.title Date $line.date"
}

Один из приемов, который мы хотим применить, — это сохранить наших авторов уникальными по имени, поэтому, даже если они появляются в нескольких строках, мы хотим создать их только один раз, а затем оставить их рядом при следующей
ссылке.


Запись
Для простоты примера мы просто используем карту. Если вам нужно сэкономить память, вы можете рассмотреть более эффективную структуру данных и двойной проход.
Я бы рекомендовал отсортированный массив имен, где индекс массива равен идентификатору узла, поэтому вы можете использовать Arrays.binarySearch (авторы, имя) для него, чтобы найти идентификатор узла автора.

Мы определяем два перечисления, одно для меток и одно для типов отношений.

enum Labels implements Label { Author, Article }
enum Types implements RelationshipType { WROTE }

Поэтому при чтении наших данных, мы теперь проверить , если мы уже знаем автор, если нет, то мы создаем Автор -node и кэшировать узел идентификатор по имени.
Затем мы создаем Article -node и соединяем оба с WROTE -отношением .

  for (line in parseCsv(csv)) {
     name = line.author
     if (!authors[name]) {
        authors[name] = batch.createNode([name:name],Labels.Author)
     }
     date = format.parse(line.date).time
     article = batch.createNode([title:line.title, date:date],Labels.Article)
     batch.createRelationship(authors[name] ,article, Types.WROTE, NO_PROPS)
     trace()
  }

Вот и все.

Я запустил импорт данных с помощью [a href = «https://www.kaggle.com/c/kdd-cup-2013-author-paper-identification-challenge/data»] авторского конкурса Kaggle, в котором приняли участие 12M Автор → Отношения с бумагами ,

При импорте использовался слегка измененный скрипт, который позаботился о 3 файлах авторов, статьях и сопоставлении.
Он загружал 12-метровые строки, 1,8 млн. Авторов и 1,2 млн. Статей за 175 секунд, занимая около 1-2 с на 100 тыс. Строк.

groovy import_kaggle.groovy papers.db ~/Downloads/kaggle-author-paper

Total 11.160.348 rows 1.868.412 Authors and 1.172.020 Papers took 174.122 seconds.

Вы можете найти полный сценарий в этом GitHub Gist .

Если вы заинтересованы в том, чтобы встретиться со мной, получить больше удовольствий (полный рабочий день, хакатон) или развлечься с базой данных графиков в целом,
не стесняйтесь присоединиться к нам 22 октября 2014 года в Сан-Франциско на конференцию GraphConnect этого года по всем вопросам Neo4j.