Listing People

If you open click on the People link in the main navigation, you will see a paginated list of actors and directors.

A list of people can be retrieved by calling the http://localhost:3000/api/people endpoint.

The list is populated by the all() method in the PeopleService.

java
neoflix/services/PeopleService.java
public List<Map<String,Object>> all(Params params) {
    // TODO: Get a list of people from the database
    if (params.query() != null) {
        return AppUtils.process(people.stream()
                .filter(p -> ((String)p.get("name"))
                        .contains(params.query()))
                .toList(), params);
    }
    return AppUtils.process(people, params);
}

This person lists vary slightly from the movie lists because this features a Search by Name input.

When this value is set, an additional q parameter is passed to tx.run(), and if defined, the query adds an additional CONTAINS predicate.

cypher
Find People with CONTAINS predicate
MATCH (p:Person)
WHERE $q IS NULL OR p.name CONTAINS $q
RETURN p { .* } AS person
ORDER BY p.name ASC
SKIP $skip
LIMIT $limit

Using Text Indexes

The STARTS WITH, ENDS WITH and CONTAINS predicates are case-sensitive. If you are looking for a case-insensitive search, you should consider setting up a full-text schema index.

Your Task

  • Modify the all() method to query Neo4j and return a list of people.

  • If the q parameter is defined, the WHERE clause should check that the name property contains the value provided.

    • Hint: You can use a null check within the query to handle the case in the WHERE clause when the parameter has no value.

  • Remember to auto-close the session and use the toMap() function within a list() function on tx.run results to convert the values to native Java types.

  • For sorting we have to use string-replacement again to set the field and direction to sort by

  • For pagination we can just pass the parameters from the params object

Click to reveal the completed all() method
java
neoflix/services/PeopleService.java
public List<Map<String,Object>> all(Params params) {
    // Open a new database session
    try (var session = driver.session()) {
        // Get a list of people from the database
        var res = session.executeRead(tx -> {
            String statement = String.format("""
                    MATCH (p:Person)
                    WHERE $q IS null OR p.name CONTAINS $q
                    RETURN p { .* } AS person
                    ORDER BY p.`%s` %s
                    SKIP $skip
                    LIMIT $limit
                    """, params.sort(Params.Sort.name), params.order());
            return tx.run(statement
                        , Values.parameters("q", params.query(), "skip", params.skip(), "limit", params.limit()))
                    .list(row -> row.get("person").asMap());
        });

        return res;
    } catch(Exception e) {
        e.printStackTrace();
    }
    return List.of();
}

Testing

To test that this functionality has been correctly implemented, run the following code in a new terminal session:

sh
Running the test
mvn test -Dtest=neoflix._14_PersonListTest

The test file is located at src/test/java/neoflix/_14_PersonListTest.java.

Are you stuck? Click here for help

If you get stuck, you can see a working solution by checking out the 14-person-list branch by running:

sh
Check out the 14-person-list branch
git checkout 14-person-list

You may have to commit or stash your changes before checking out this branch. You can also click here to expand the Support pane.

Verifying the Test

What is the name of the first person in the database in alphabetical order?

As part of the test suite, the final test will log the name of the first person to appear in the database in name order.

Paste the name of the person the box below without quotes or whitespace and click Check Answer.

  • ✓ 'Snub' Pollard

Hint

You can also find the answer by running the following Cypher statement:

cypher
MATCH (p:Person)
RETURN p.name
ORDER BY p.name ASC LIMIT 1

Copy the answer without any double quotes or whitespace.

Lesson Summary

In this Challenge, you implemented the all() method in the PeopleService to return a paginated list of people from the Neo4j database and implemented a conditional WHERE clause on the Person name property.

In the next Challenge, you will retrieve an individual’s details from the database.