2016-04-17 7 views
0

Ich versuche einige Abfragen auf einigen Neo4j-Datenbanken zu testen, die sich in der Datenmenge unterscheiden. Wenn ich diese Abfragen auf kleine Datenmenge teste, läuft alles richtig und die Ausführungszeit ist klein, aber wenn ich Abfragen mit 2794 Knoten und 94863 Relationen in der Datenbank starte, dauert es sehr lange, bis der folgende Fehler in der Neo4j API auftritt: Java Heap-Speicher Neo.DatabaseError.General.UnknownFailure enter image description here erste Abfrage:Neo4j: Java-Heap-Speicherfehler nach Abfrageabfrage mit eindeutiger Abfrage erstellen

MATCH (u1:User)-[r1:Rated]->(m:Movie)<-[r2:Rated]-(u2:User) 
WITH 1.0*SUM(r1.Rate)/count(r1) as pX, 
1.0*SUM(r2.Rate)/count(r2) as pY, u1, u2 
MATCH (u1:User)-[r1:Rated]->(m:Movie)<-[r2:Rated]-(u2:User) 
WITH SUM((r1.Rate-pX)*(r2.Rate-pY)) as pomProm, 
SQRT(SUM((r1.Rate-pX)^2)) as sumX, 
SQRT(SUM((r2.Rate-pY)^2)) as sumY, pX,pY,u1,u2 
CREATE UNIQUE (u1)-[s:SIMILARITY1]-(u2) 
SET s.value = pomProm/(sumX * sumY) 

und zweite Abfrage

MATCH (u1:User)-[r1:Rated]->(m:Movie)<-[r2:Rated]-(u2:User) 
WITH SUM(r1.Rate * r2.Rate) AS pomProm, 
SQRT(REDUCE(r1Pom = 0, i IN COLLECT(r1.Rate) | r1Pom + toInt(i^2))) AS r1V, 
SQRT(REDUCE(r2Pom = 0, j IN COLLECT(r2.Rate) | r2Pom + toInt(j^2))) AS r2V, 
u1, u2 
CREATE UNIQUE (u1)-[s:SIMILARITY2]-(u2) 
SET s.value = pomProm/(r1V * r2V) 

Daten in der Datenbank aus folgenden Java-Code generiert werden:

public enum Labels implements Label { 
    Movie, User 
} 

public enum RelationshipLabels implements RelationshipType { 
    Rated 
} 

public static void main(String[] args) throws IOException, BiffException { 
    Workbook workbook = Workbook.getWorkbook(new File("C:/Users/User/Desktop/DP/dvdlist.xls")); 
    Workbook names = Workbook.getWorkbook(new File("C:/Users/User/Desktop/DP/names.xls")); 
    String path = new String("C:/Users/User/Documents/Neo4j/test7.graphDatabase"); 
    GraphDatabaseFactory dbFactory = new GraphDatabaseFactory(); 
    GraphDatabaseService db = dbFactory.newEmbeddedDatabase(path); 
    int countMovies = 0; 
    int numberOfSheets = workbook.getNumberOfSheets(); 
    IndexDefinition indexDefinition; 
    try (Transaction tx = db.beginTx()) { 
     Schema schema = db.schema(); 
     indexDefinition = schema.indexFor(DynamicLabel.label(Labels.Movie.toString())) 
       .on("Name") 
       .create(); 
     tx.success(); 
    } 
    try (Transaction tx = db.beginTx()) { 
     Schema schema = db.schema(); 
     indexDefinition = schema.indexFor(DynamicLabel.label(Labels.Movie.toString())) 
       .on("Genre") 
       .create(); 
     tx.success(); 
    } 
    try (Transaction tx = db.beginTx()) { 
     Schema schema = db.schema(); 
     indexDefinition = schema.indexFor(DynamicLabel.label(Labels.User.toString())) 
       .on("Name") 
       .create(); 
     tx.success(); 
    } 
    try (Transaction tx = db.beginTx()) { 

     for (int i = 0; i < numberOfSheets; i++) { 
      Sheet sheet = workbook.getSheet(i); 
      int numberOfRows = 6000;//sheet.getRows(); 
      for (int j = 1; j < numberOfRows; j++) { 
       Cell cell1 = sheet.getCell(0, j); 
       Cell cell2 = sheet.getCell(9, j); 
       Node movie = db.createNode(Labels.Movie); 
       movie.setProperty("Name", cell1.getContents()); 
       movie.setProperty("Genre", cell2.getContents()); 

       countMovies++; 

      } 

     } 
     tx.success(); 
    } catch (Exception e) { 
     System.out.println("Something goes wrong!"); 
    } 

    Random random = new Random(); 
    int countUsers = 0; 
    Sheet sheetNames = names.getSheet(0); 
    Cell cell; 
    Node user; 

    int numberOfUsers = 1500;//sheetNames.getRows(); 
    for (int i = 0; i < numberOfUsers; i++) { 
     cell = sheetNames.getCell(0, i); 
     try (Transaction tx = db.beginTx()) { 
      user = db.createNode(Labels.User); 
      user.setProperty("Name", cell.getContents()); 
      List<Integer> listForUser = new ArrayList<>(); 

      for (int x = 0; x < 1000; x++) { 
       int j = random.nextInt(countMovies); 
       if (!listForUser.isEmpty()) { 
        if (!listForUser.contains(j)) { 
         listForUser.add(j); 
        } 
       } else { 
        listForUser.add(j); 
       } 
      } 
      for (int j = 0; j < listForUser.size(); j++) { 
       Node movies = db.getNodeById(listForUser.get(j)); 
       int rate = 0; 

       rate = random.nextInt(10) + 1; 

       Relationship relationship = user.createRelationshipTo(movies, RelationshipLabels.Rated); 
       relationship.setProperty("Rate", rate); 

      } 
      System.out.println("Number of user: " + countUsers); 
      tx.success(); 
     } catch (Exception e) { 
      System.out.println("Something goes wrong!"); 
     } 
     countUsers++; 
    } 

    workbook.close(); 
} 

}

Weiß jemand, wie dieses Problem zu lösen? Oder gibt es einen Umweg, wie man Ergebnisse aus diesen Abfragen in einer Datenbank mit einer großen Datenmenge erhält? Oder eine Abfrage oder Einstellungsverbesserung? Ich werde es wirklich zu schätzen wissen.

Antwort

0

Möglicherweise müssen Sie den verfügbaren Speicherplatz für Neo4j konfigurieren. Sie können Neo4j Server-Heap-Größe konfigurieren conf/neo4j-wrapper.conf bearbeite:

wrapper.java.maxmemory=NUMBER_OF_MB_HERE 

Siehe für weitere Informationen this page.

Wenn Sie jedoch Ihre Abfragen (die globale globale Graphenoperationen durchführen) betrachten, sollten Sie sie in Stapeln betrachten. Zum Beispiel:

// Find users with overlapping movie ratings 
MATCH (u1:User)-[:RATED]->(:Movie)<-[:RATED]-(u2:User) 
// only for users whose similarity has not yet been calculated 
WHERE NOT exists((u1)-[:SIMILARITY]-(u2)) 
// consider only up to 50 pairs of users 
WITH u1, u2 LIMIT 50 
// compute similarity metric and set SIMILARITY relationship with coef 
... 

Dann diese Abfrage wiederholt ausführen, bis Sie die Ähnlichkeitsmetrik für alle Benutzer mit überlappenden Filmbewertungen berechnet haben.

+0

Danke, Speicher hat mir wirklich geholfen. Und ich werde deinen zweiten Ratschlag versuchen. – user3904604

+0

Ich versuche Ihren Code, gibt es eine Möglichkeit, wie diese Abfrage in Chiffre Schleife? – user3904604

+0

Nicht in Cypher, sondern im Client nur nach Ergebnissen in einer 'while (results)' - Schleife suchen –