cancel
Showing results for 
Search instead for 
Did you mean: 

Get all direct relationships of an entity:More than one matching node in the record

ccnice99
Node

I want to get all direct relationships of an entity.(This entity may be a head entity or a tail entity.)
PeopleRepository.java

    @Query("MATCH p=(e1:People{name:$name})-[rel*1]-(e2) return e1,rel,e2")
    List<Triple> findAllDirectTriple(String name);

Triple.java

public class Triple {
    People head;
    Relation relation;
    People tail;
}

Error Mesaage

org.springframework.data.mapping.MappingException: More than one matching node in the record.

How can I solve this problem?Thank u

4 REPLIES 4

gerrit_meier
Neo4j
Neo4j

There are several things in your question.
The error you are facing comes from SDN not knowing which entity to choose from to map. So there might be already mapped objects in the cache or the record contains the same entity twice.
The root problem is that you are apparently trying to map not an entity but an aggregate. This is not possible with the repositories because they are entity-focused.
We have you covered here: Use the Neo4jClient and rely on the existing mapping functions for People. The relationship needs to get manually mapped because it is not a real entity. How to do this is described in the documentation: Spring Data Neo4j

OK,I have tried using the Neo4jClient.But I have another problem.
Inside the mappedBy, I have tried two ways below.

List<Object> relations_1 = record.get("relation").asList();
List<String> relations_2 = record.get("relation").asList(rel -> rel.toString());

The results of the two ways are different!

relations_1.get(0) = Friend
relations_2.get(0) = "Friend"

It's so weird!Could you help me ?
Thans a lot.

I assume that the first one is a Driver (String)Value. There is a asString() on the value that unwraps it into a Java String.

From the Neo4jClient perspective, I was thinking of something like this:

BiFunction<TypeSystem, MapAccessor, People> mappingFunction = mappingContext.getRequiredMappingFunctionFor(People.class);
client.query("MATCH p=(e1:People{name:$name})-[rel*1]-(e2) return e1,rel,e2")
	.fetchAs(Triple.class)
	.mappedBy((typeSystem, record) -> {
		People person1 = mappingFunction.apply(typeSystem, record.get("e1").asNode());
		People person2 = mappingFunction.apply(typeSystem, record.get("e2").asNode());
		Relationship rel = record.get("rel").asRelationship();

		return new Triple(person1, rel, person2);
	})
	.all();
}

In this case you would keep the Driver Relationship in the Triple. It has access to start and end that gives you the information about the outgoing and incoming id of the connected nodes.

You're right!
I changed toString() to asString(),it worked!
Thank you very much!