Get Node 'Tome Hanks' with all related Movies

Hi,

at the moment, I'm trying to understand cypher. I started with the Cypher Query example from the website.

If, try the following cypher query.

- MATCH (tom:Person {name: 'Tom Hanks'}) RETURN tom

Then I got three nodes with the same related movies. I don't know why. Maybe these three nodes are another example. For my understanding, it is better to have a query to get the actor 'Tom Hanks' and his related movies.

I tried also this other example from the Querying with Cypher - Developer Guides (neo4j.com)

In this case i got three Nodes "That Thing You Do"

- MATCH (tom:Person {name:'Tom Hanks'})-[rel:DIRECTED]-(movie:Movie) RETURN tom.name, movie.title

Your first query should only give you one node, which is Person node with the name ‘Tom Hanks’. You got something other than that? Is this your local database? If so, maybe you added additional Tom hanks nodes while you have been learning.

Hi @glilienfield ,

your assumption was correct. I duplicated with another example these nodes. I removed these Nodes and found also a solution to get all related movie titles. These works also in Java.

- Match (tom:Person{name: 'Tom Hanks'})-[r]->(m) Return m.title

I have one last question. I tried to check in Java is the Node "Tom Hanks available".

These following example doesn't work in Java. Do you have an Idea ?

- MATCH (tom:Person) WHERE tom.name = "Tom Hanks" RETURN tom

public List getPeople() {
try (var session = driver.session()) {
return session.executeRead(tx -> {
List names = new ArrayList<>();
//var result = tx.run("Match (tom:Person{name: 'Tom Hanks'})-[r]->(m) Return m.title"); // Tom Hanks ist das gesuchte schlüssel wort
var result = tx.run("MATCH (tom:Person) WHERE tom.name = 'Tom Hanks' RETURN tom"); // Tom Hanks ist das gesuchte schlüssel wort
while (result.hasNext()) {
names.add(result.next().get(0).asString());
}
return names;
});
}
}

If you want to determine the existence of a node, you could try the following. It will return a boolean value.

optional match(n:Person{name:'Tom Hanks'})
return n is not null as isExists

The above will return multiple rows if there are duplicates. You can avoid that if it would be an issue with the following query:

optional match(n:Person{name:'Tom Hanks'})
return size(collect(distinct n)) > 0

I also don't like to use iterators. I instead prefer to use steams or the 'list' method on the 'Result' object to create a list from the result.

list method:

public List<String> getPeople() {
	try(Session session = driver.session()) {
	    return session.readTransaction(tx -> tx.run("Match (tom:Person{name: 'Tom Hanks'})-[r]->(m) Return m.title as title")
	            .list(v -> v.get("title").asString()));
	}
}

stream:

public List<String> getPeople() {
	try(Session session = driver.session()) {
    return session.readTransaction(tx -> tx.run("Match (tom:Person{name: 'Tom Hanks'})-[r]->(m) Return m.title as title")
            .stream()
            .map(v -> v.get("title").asString())
            .collect(Collectors.toList()));
	}
}

Hi ,

I tried the last both example. Both are working well. But how can I execute first both query's. My understanding at the moment is the function readTransaction returns a list.

The readTransaction is declared as follows. As such, it will return whatever type is returned by the TransactionWork's 'execute' method. In the case below, this is what is returned by 'tx.run'

 <T> T readTransaction(TransactionWork<T> var1);

The following query will tell you a Person node exists for 'person'. As you can see, it returns a Boolean.

public Boolean getPerson(String person, Driver driver) {
        try (Session session = driver.session()) {
            return session.readTransaction(tx -> tx.run(
                            "optional match(n:Person{name: $person}) " +
                                    "return size(collect(distinct n)) > 0 as isExists", Map.of("person", person))
                    .single().get("isExists").asBoolean());
        }
    }

Thanks for your support @glilienfield !