В конце февраля мы взглянули на пакетный импортер Майкла Хангера . Это отличный инструмент для быстрой загрузки миллионов узлов и связей в Neo4j. Единственное, чего не хватало, это индексирования … Я говорю, потому что я только что отправил запрос на добавление, чтобы добавить эту функцию. Давайте рассмотрим, как это было сделано, чтобы вы получили представление о том, как выглядит API пакетного импорта Neo4j, и в следующей статье блога я покажу вам, как генерировать данные, чтобы использовать их в своих интересах.
Первым делом мне нужно было обновить файл pom.xml, включив в него последнюю версию Neo4j и зависимость от индекса Lucene.
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>1.8.M05</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-lucene-index</artifactId>
<version>1.8.M05</version>
</dependency>
Функция пакетной вставки была перемещена в org.neo4j.unsafe, чтобы напомнить вам, что ее следует использовать только при первой загрузке.
import org.neo4j.unsafe.batchinsert.BatchInserter; import org.neo4j.unsafe.batchinsert.BatchInserters; import org.neo4j.unsafe.batchinsert.BatchInserterImpl; import org.neo4j.unsafe.batchinsert.BatchInserterIndexProvider; import org.neo4j.unsafe.batchinsert.BatchInserterIndex; import org.neo4j.unsafe.batchinsert.LuceneBatchInserterIndexProvider;
Мы создаем LuceneBatchInserterIndexProvider с именем lucene из БД:
db = BatchInserters.inserter(graphDb.getAbsolutePath(), config); lucene = new LuceneBatchInserterIndexProvider(db);
Давайте посмотрим на метод importNodeIndexes:
private void importNodeIndexes(File file, String indexName, String indexType) throws IOException {
BatchInserterIndex index;
if (indexType.equals("fulltext")) {
index = lucene.nodeIndex( indexName, stringMap( "type", "fulltext" ) );
} else {
index = lucene.nodeIndex( indexName, EXACT_CONFIG );
}
BufferedReader bf = new BufferedReader(new FileReader(file));
final Data data = new Data(bf.readLine(), "\t", 1);
Object[] node = new Object[1];
String line;
report.reset();
while ((line = bf.readLine()) != null) {
final Map<String, Object> properties = map(data.update(line, node));
index.add(id(node[0]), properties);
report.dots();
}
report.finishImport("Nodes into " + indexName + " Index");
}
Мы передаем переменную indexType, чтобы решить, будет ли этот индекс точным или полнотекстовым. Мы создаем индекс с помощью lucene.nodeIndex. Затем мы читаем значения, которые нужно добавить в наш индекс, из переданного файла. Как только мы фиксируем ключ и значения из нашего файла, мы просто передаем их вместе с идентификатором нашего узла в метод add.
Давайте посмотрим на importRelationshipIndexes:
private void importRelationshipIndexes(File file, String indexName, String indexType) throws IOException {
BatchInserterIndex index;
if (indexType.equals("fulltext")) {
index = lucene.relationshipIndex( indexName, stringMap( "type", "fulltext" ) );
} else {
index = lucene.relationshipIndex( indexName, EXACT_CONFIG );
}
BufferedReader bf = new BufferedReader(new FileReader(file));
final Data data = new Data(bf.readLine(), "\t", 1);
Object[] rel = new Object[1];
String line;
report.reset();
while ((line = bf.readLine()) != null) {
final Map<String, Object> properties = map(data.update(line, rel));
index.add(id(rel[0]), properties);
report.dots();
}
report.finishImport("Relationships into " + indexName + " Index");
}
Он практически идентичен, но мы создаем индексы отношений вместо индексов узлов. Наконец, нам нужно отключить Lucene, а также наш график.
private void finish() {
lucene.shutdown();
db.shutdown();
report.finish();
}
Вы можете посмотреть полный исходный код по адресу https://github.com/maxdemarzi/batch-import .
Чтобы использовать его, мы добавим четыре аргумента для каждого индекса в командной строке:
Чтобы создать полнотекстовый индекс узлов с именем users, использующий node_index.csv:
node_index users fulltext nodes_index.csv
Чтобы создать точный индекс отношений с именем работал, используя rels_index.csv:
rel_index worked exact rels_index.csv
Пример командной строки:
java -server -Xmx4G -jar ../batch-import/target/batch-import-jar-with-dependencies.jar neo4j/data/graph.db nodes.csv rels.csv node_index users fulltext nodes_index.csv rel_index worked exact rels_index.csv
Мы ожидаем, что node_index.csv будет выглядеть так:
id name language 1 Victor Richards West Frisian 2 Virginia Shaw Korean 3 Lois Simpson Belarusian 4 Randy Bishop Hiri Motu 5 Lori Mendoza Tok Pisin
Мы ожидаем, что rels_index.csv будет выглядеть так:
id property1 property2 0 cwqbnxrv rpyqdwhk 1 qthnrret tzjmmhta 2 dtztaqpy pbmcdqyc
Столбцы id ссылаются на идентификатор узла или отношения. Заголовки — это ключи индекса, а значения в каждой строке — это то, что будет добавлено в индекс для этого ключа.
Следуйте за мной в Твиттере на @maxdemarzi, и вы узнаете, когда будет опубликовано следующее сообщение в блоге, которое использует эти функции.
