2016-04-02 12 views
2

CONTEXT (derzeit Neo4j Templat verwenden): durch eine Neo4j Datenbank gesichertWie kann ich GraphRepositories verwenden komplexe POJO die mit einer bestimmten Tiefe zurückzukehren

Ich arbeite an einer Java-Frühling Web-Anwendung. Ich habe ein Objekt "Student", das eine Reihe von "Modulen" und "Kursen" belegt hat. Die Beziehung ist über "reiche Beziehungs" -Knoten "RR_TakenModule" und "RR_TakenCourse" verbunden, die eine Grad-Eigenschaft spezifizieren.

public class Student extends DomainObject { 
    String fullName; 
    Gender gender; 
    Collection<RR_TakenModule> modulesTaken; 
    Collection<RR_TakenCourse> coursesTaken; 
    DateTime yearStarted; 

auf diese Weise ich für einen Studenten fragen könnte, die

PROBLEM 74% in einem Modul bekam:

Ich kann nicht ein "tief" Objekt zurück, von der GraphRepository eingerichtet. Dh ich kann keinen Student mit den Eigenschaften "modulesTaken" und "coursesTaken" ausgeben. Ich habe Online mehrere Ansätze gesehen, wie die CYPHER Abfrage versucht:

MATCH (student:Student) -[:MODULES_TAKEN]-> (rr:RR_TakenModule) -[:MODULE]-> (m:Module) RETURN student, COLLECT(rr) as modulesTaken 

, die die RR_TakenModules in das Objekt dynamisch über die Eigenschaftsnamen zur Karte in Anspruch genommen wird. Es tut dies nicht für mich und gibt einen "Error mapping GraphModel zu Instanz von com.domain.Actors.Student" Fehlercode zurück. Beachten Sie jedoch, dass die Gruppierung korrekt ist, wenn die Abfrage cipher in der Schnittstelle localhost: 7474 ausgeführt wird. Eindeutige Zuordnung ist das Problem.

Derzeit habe ich die Vorlage und Map-Ansatz übernommen. Verwenden von Neo4jOperations und des Result-Objekts. Das funktioniert, bedeutet jedoch, dass ich Iteratoren ausschreiben muss, die Werte durchlaufen und basierend auf den Schlüssel/Wert-Paaren im Ergebnisobjekt Werte zuweisen. Dies führt zu einer hohen Wartung und einer größeren Fehlerwahrscheinlichkeit.

Umsah ihre verwendeten Optionen wie @Fetch zu sein, und Tiefe in Neo4jTemplate Abfragen spezifizieren, jedoch nicht dieser Methoden scheinen in meiner Version zu sein (die meisten erscheinen abgeschrieben werden)

FRAGE:

Gibt es eine Möglichkeit, Unterobjekte (dh "Collection Prop" und "Set Prop") eines Neo4j Entitätsobjekts über Graph Repositories abzubilden. Ich weiß, es gibt vordefinierte Methoden wie "findOne", die einen Tiefenparameter haben, aber ich möchte eine ähnliche Implementierung auf meine benutzerdefinierten Abfragen anwenden.

Alternativ gibt es eine Lösung für dynamisch ein Neo4jOperations Mapping-Ergebnis Objekt zu einem Java-Objekt ohne einige benutzerdefinierte json-Parser zu definieren

BAUVARIANTEN:

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.3.1.RELEASE</version> 
</parent> 

<properties> 
    <java.version>1.8</java.version> 
    <spring-data-neo4j.version>4.0.0.RELEASE</spring-data-neo4j.version> 
    <spring-data-releasetrain.version>Gosling-RELEASE</spring-data-releasetrain.version> 
</properties> 
+0

4.1.1.RELEASE eine bessere Unterstützung für die Zuordnung von Personen aus benutzerdefinierte Abfragen hat. Bitte aktualisieren Sie auf diese Version. Mehr Infos hier: http://grafhaware.com/neo4j/2016/04/06/mapping-query-entities-sdn.html – Luanne

Antwort

0

Nach einem Blick in die default „FindOne (knoteid, depth) "Methode GraphRepositor bietet eine Lösung, die für mich funktioniert.

Ich formatiere die Abfrage als MATCH (n:Entity) WITH n MATCH p=(n)-[*0..4]->(m) RETURN p wobei Entity der Name Ihrer Basiseinheit ist. Ich kann nicht rechtfertigen warum, aber dieses Format wird das Ergebnis dynamisch Ihrem jeweiligen POJO zuordnen.

Hinweis: Sie können die Tiefe (* 0..4) angeben, um anzugeben, wie tief ein POJO gefüllt wird. Es ist auch erwähnenswert, dass die Beziehung -[]-> nicht -[]- verwendet, was die Standardbeziehung für findOne (nodeid, depth) ist.Wenn dies nicht funktioniert, ist es möglich, dass Sie nicht die neueste Version von Neo4j OGM haben.

0

Spring Data Neo4j (SDN) füllt die referenzierten (nach Beziehung) Knoten im zurückgegebenen Knoten nicht auf. Es wird jedoch die fullName und gender Eigenschaften (unter der Annahme, dass Gender eine Enum ist, so dass eine Zeichenfolge problemlos zugeordnet werden kann) bevölkern.

In Ihrer Abfrage oben geben Sie einen Student-Knoten und eine Auflistung von RR_TakenModule zurück, aber Spring weiß nicht, wie Sie dies zuordnen, da es keine Klasse gibt, die diese beiden Ergebnisse enthält. Sie müssen für diesen Fall ein explizites Ergebnis definieren. Ich schlage vor, die folgenden:

@NodeEntity(label = "Student") 
public class Student extends DomainObject { 
    @Property(name = "studentId") 
    private String studentId; //you want to have this 
    @Property(name = "fullName") 
    private String fullName; 
    @Property(name = "gender") 
    private Gender gender; //assuming its an Enum 
    @Relationship(type = "MODULES_TAKEN") // Relationship.OUTGOING is default 
    private Set<RR_TakenModule) modulesTaken; 
} 

Dann ein Repository definieren

public interface StudentRepository extends GraphRepository<Student> { 

    @Query("MATCH (s:Student {studentId:{studentId}})-[:MODULES_TAKEN]->(m:RR_TakenModule) RETURN s AS student, collect(DISTINCT m) AS modulesTaken") 
    public StudentWithModulesTakenResult getByUserIdWithModulesTaken(@Param("studentId") String studentId) 
} 

und das jeweilige Ergebnis

@QueryResult 
public class StudentWithModulesTakenResult { 
    private Student student; 
    private Set<RR_TakenModule> modulesTaken; 
    //only getters, no setters 
}