Вот код, который вы использовали бы с Neo4j-Batch-Inserter для импорта записей вызовов, вместо того, чтобы генерировать данные на лету, вы, конечно, прочитали бы их из файла и соответствующим образом разбили каждую запись.
import org.apache.commons.io.FileUtils;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.BatchInserterIndex;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.index.impl.lucene.LuceneBatchInserterIndexProvider;
import org.neo4j.kernel.impl.batchinsert.BatchInserterImpl;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import static org.neo4j.helpers.collection.MapUtil.map;
public class CallRecordImportBatch {
public static final int MILLION = 1000000;
public static final int BATCH_SIZE = MILLION;
public static final int CALLS = 45 * MILLION;
public static final int USERS = CALLS / 100;
public static final File STORE_DIR = new File("target/calls_"+ CALLS);
private static final Random rnd = new Random();
enum MyRelationshipTypes implements RelationshipType {CALLED}
private static String randomPhoneNumber() {
final int phoneNumber = rnd.nextInt(USERS);
return String.format("%013d", phoneNumber);
}
public static void main(String[] args) throws IOException {
long time = System.currentTimeMillis();
CallRecordImportBatch importBatch = new CallRecordImportBatch();
importBatch.createGraphDatabase();
System.out.println((System.currentTimeMillis() - time) + " ms: "+ "Create Database");
}
private BatchInserterImpl db;
private BatchInserterIndex phoneNumberIndex;
private void createGraphDatabase() throws IOException {
if (STORE_DIR.exists()) FileUtils.cleanDirectory(STORE_DIR);
STORE_DIR.mkdirs();
db = new BatchInserterImpl(STORE_DIR.getAbsolutePath(),
MapUtil.stringMap("cache_type", "weak",
"neostore.nodestore.db.mapped_memory", "500M",
"neostore.relationshipstore.db.mapped_memory", "2000M",
"neostore.propertystore.db.mapped_memory", "1000M",
"neostore.propertystore.db.strings.mapped_memory", "0M",
"neostore.propertystore.db.arrays.mapped_memory", "0M"
));
final LuceneBatchInserterIndexProvider indexProvider = new LuceneBatchInserterIndexProvider(db);
phoneNumberIndex = indexProvider.nodeIndex("Caller", MapUtil.stringMap("type", "exact"));
phoneNumberIndex.setCacheCapacity("Caller", 1000000);
long time = System.currentTimeMillis();
Map<String,Long> cache = new HashMap<String,Long>(USERS);
try {
for (int call=0;call< CALLS;call++) {
if (call % BATCH_SIZE == 0) {
System.out.println((System.currentTimeMillis() - time) + " ms: "+ String.format("calls %d callers %d", call, cache.size()));
time = System.currentTimeMillis();
}
final String callerNumber = randomPhoneNumber();
final int duration = (int) (System.currentTimeMillis() % 3600);
final String calleeNumber = randomPhoneNumber();
long caller = getOrCreateCaller(cache, callerNumber);
long callee = getOrCreateCaller(cache, calleeNumber);
db.createRelationship(caller, callee, MyRelationshipTypes.CALLED, map("duration", duration));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println((System.currentTimeMillis() - time) + " ms: " + String.format("calls %d callers %d", CALLS, cache.size()));
indexProvider.shutdown();
db.shutdown();
}
private Long getOrCreateCaller(Map<String, Long> cache, String number) {
final Long callerId = cache.get(number);
if (callerId!=null) return callerId;
long caller = createCaller(number);
cache.put(number, caller);
return caller;
}
private long createCaller(String number) {
long caller = db.createNode(map("Number", number));
phoneNumberIndex.add(caller, map("Number", number));
phoneNumberIndex.flush();
return caller;
}
}