Database Reference
In-Depth Information
After the Node properties are created, the User class has a number of encapsulated domain objects that have the
@RelatedTo
annotation. The
@RelatedTo
has a type, such as
MADE
, and a direction, such as
OUTGOING
or
INCOMING
, as
well as specifying the class on the other side of the relationship.
As suggested in the chapter on modeling, one way to think about directed relationships is by first constructing a
Cypher snippet or a short phrase to consider direction, such as “user-[:made]->purchase” or “a user made a purchase”.
In some cases, the relationship will be bidirectional, such as FOLLOWS. Although it is possible to analyze the
relationship without direction in this case, the direction serves as an expression of the relationship.
Spring Data Repositories
For each object type in the domain, the sample application has at least one corresponding Spring Data repository
interface. One of the intentions of the Spring Data repositories is to save you from coding methods for the most
commonly used data operations.
For the sample application, all of the repository interfaces are located in the
com.practicalneo4j.graphstory.repository
package and extend the
GraphRepository
interface. By extending the
GraphRepository
interface, the repositories will have access to a number of commonly used methods, such as a
save
method. In addition, repositories can include (1) your own methods via a
@Query
annotation, which takes a Cypher
query as a property, and (2) the very handy and flexible derived finder methods.
Each of the derived methods begins with prefix, like
findBy
in the case of the finder methods, and then is
followed by the necessary properties, conjunctions, and operators to create a Cypher query. For example, the
findByUsername
method, shown in Listing 11-17, will use the
@Indexed
field
username
to form a Cypher query as
start user=node:User(username = {0}) return user
.
In the case of the additional methods in
UserRepository
, you will use Cypher queries with parameters supplied
by the method. For example, the
searchByUsername
method in Listing 11-30 looks for users to follow based on a
search of the
User
entities. It performs a
MATCH
on the
currentusername
parameter, which is set via
@Param("c")
.
The query also performs a wild card search using
WHERE
on the username, which is set via
@Param("u")
. This
part of the
WHERE
also ignores the user found in the
MATCH currentusername
part of the query. Finally, the query
also ignores all of the users the
currentusername
is
already
following by using the Boolean operator
NOT
and the
directional relationship of
FOLLOWS
.
Listing 11-17.
The UserRepository Interface
public interface
UserRepository
extends GraphRepository<User> {
User
findByUsername
(String username);
@Query(
// match users and user by username via param 'c'
// where n.username WILDCARD on param 'u'
// but is not the current user
// and don't return users already being followed
// return list of users
" MATCH (n:User), (user { username:{c}}) " +
" WHERE (n.username =~ {u} AND n <> user) " +
" AND (NOT (user)-[:FOLLOWS]->(n)) " +
" RETURN n")
List<User>
searchByUsername
(@Param("c") String currentusername,
@Param("u") String username);