Neo4J Lab - Intermediate
This lab won't show the steps in much detail, instead, it will be shorter and you need to figure out (with some tips) how to implement it.
Try to, first implement, and later, see the solution!
1. Define the Person
Entity Class
- Create a class called
Person
in theexpert.os.labs.persistence
package - Define the class with the
@Entity
annotation from thejakarta.nosql
package -
Add the following
private
fields:Annotation Type Name @Id
Long
id
@Column
String
name
@column
long
age
@Column
String
occupation
@Column
Double
salary
-
Implement constructors, getter methods,
equals
,hashCode
, andtoString
methods
Solution
Click to see...
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
@Entity
public class Person {
@Id
private Long id;
@Column
private String name;
@Column
private Long age;
@Column
private String occupation;
@Column
private Double salary;
public Person() {
}
public Person(String name, Long age, String occupation, Double salary) {
this.name = name;
this.age = age;
this.occupation = occupation;
this.salary = salary;
}
// other methods ignored
}
2. Implement the Builder class
Steps
- Create a class called
PersonBuilder
in theexpert.os.labs.persistence
package - Add the same fields we had previously added to the
Person
class, without the annotations - Add the builder methods for each field
- Add the
build()
method creating a new instance ofPerson
using its constructor - In the
Person
class add the builder method referring to thePersonBuilder
Solution
Click to see...
public class PersonBuilder {
private Long id;
private String name;
private Long age;
private String occupation;
private Double salary;
public PersonBuilder id(Long id) {
this.id = id;
return this;
}
public PersonBuilder name(String name) {
this.name = name;
return this;
}
public PersonBuilder age(Long age) {
this.age = age;
return this;
}
public PersonBuilder occupation(String occupation) {
this.occupation = occupation;
return this;
}
public PersonBuilder salary(Double salary) {
this.salary = salary;
return this;
}
public Person build() {
return new Person(name, age, occupation, salary);
}
}
3. Create the service class
- Create a class called
PersonService
in theexpert.os.labs.persistence
package -
Add all the fields and methods from the code below to the class
import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.eclipse.jnosql.mapping.graph.GraphTemplate; import static org.apache.tinkerpop.gremlin.process.traversal.P.between; import static org.apache.tinkerpop.gremlin.process.traversal.P.gte; @ApplicationScoped public class PersonService { @Inject private GraphTemplate graph; public Person save(Person person) { // Save a person entity to the graph database } void knows(Person person, Person friend) { // Establish a "knows" relationship between two persons } void love(Person person, Person friend) { // Establish a "knows" relationship with a "feel" attribute set to "love" } List<Person> developers() { // Retrieve a list of persons with the occupation "Developer" and salary >= 3000 and age between 20 and 25 } List<Person> whoDevelopersKnows() { // Retrieve a list of persons known by developers with salary >= 3000 and age between 20 and 25 } List<Person> both() { // Retrieve a list of persons who are developers and known by developers with salary >= 3000 and age between 20 and 25 } List<Person> couple() { // Retrieve a list of developers who are in love (have a "feel" attribute set to "love") } }
-
Take some time to understand what each method must do by reading the comments in the code or looking at the following table
Method Implementation save
Save or retrieve a person that has a name
using thetraversalVertex()
method fromgraph
knows
Create a relationship between two people using the label "knows"
love
Create a relationship between two people using the label "knows"
adding two more relationships:"feels"
and"love"
developers
Retrieve a list of people who have the occupation as "developer"
and is a"Developer"
whoDevelopersKnows
Retrieve a list of people by developers with salary >= 3000 and age between 20 and 25 both
Retrieve a list of people who are developers and known by developers with salary >= 3000 and age between 20 and 25 couple
Retrieve a list of developers who are in love (have a "feel" attribute set to "love")
Solution
Click to see...
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.jnosql.mapping.graph.GraphTemplate;
import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.P.between;
import static org.apache.tinkerpop.gremlin.process.traversal.P.gte;
@ApplicationScoped
public class PersonService {
@Inject
private GraphTemplate graph;
public Person save(Person person) {
return graph.traversalVertex().hasLabel(Person.class)
.has("name", person.getName()).<Person>next()
.orElseGet(() -> graph.insert(person));
}
void knows(Person person, Person friend) {
this.graph.edge(person, "knows", friend);
}
void love(Person person, Person friend) {
this.graph.edge(person, "knows", friend).add("feel", "love");
}
List<Person> developers() {
return graph.traversalVertex().has("occupation", "Developer")
.<Person>result().toList();
}
List<Person> whoDevelopersKnows() {
return graph.traversalVertex().has("salary", gte(3_000D))
.has("age", between(20, 25)).has("occupation", "Developer").out("knows")
.<Person>result().toList();
}
List<Person> both() {
return graph.traversalVertex().has("salary", gte(3_000D)).has("age", between(20, 25))
.has("occupation", "Developer").outE("knows").bothV().<Person>result()
.distinct().toList();
}
List<Person> couple() {
return graph.traversalVertex().has("salary", gte(3_000D)).has("age", between(20, 25))
.has("occupation", "Developer").outE("knows").has("feel", "love").bothV()
.<Person>result().distinct().toList();
}
}
4. Create the execution class
Steps
- Create a class called
AppMarketing
in theexpert.os.labs.persistence
package -
Add the necessary below code to the class
import jakarta.enterprise.inject.se.SeContainer; import jakarta.enterprise.inject.se.SeContainerInitializer; import java.util.List; public final class AppMarketing { private AppMarketing() { } public static void main(String[] args) { try (SeContainer container = SeContainerInitializer.newInstance().initialize()) { PersonService service = container.select(PersonService.class).get(); // Create and save persons using the builder Person banner = service.save(Person.builder().age(30L).name("Banner") .occupation("Developer").salary(3_000D).build()); // Create and save more persons here... // Establish "knows" and "love" relationships between persons // Use the methods provided by the PersonService to query the graph database List<Person> developers = service.developers(); List<Person> peopleWhoDeveloperKnows = service.whoDevelopersKnows(); List<Person> both = service.both(); List<Person> couple = service.couple(); // Print the results System.out.println("Developers: " + developers); System.out.println("People who Developers know: " + peopleWhoDeveloperKnows); System.out.println("Both Developers and Known Persons: " + both); System.out.println("Developers in Love: " + couple); } } }
-
Take some time to understand what each method must do by reading the comments and implementing what's necessary in this class
-
Run the
main()
method
Expected results
-
The following output
Developers has salary greater than 3000 and age between 20 and 25: [Person{id=12, name='Banner', age=30, occupation='Developer', salary=3000.0}, Person{id=13, name='Natalia', age=32, occupation='Developer', salary=5000.0}, Person{id=15, name='tony', age=22, occupation='Developer', salary=4500.0}] Person who the Developers target know: [Person{id=14, name='Rose', age=40, occupation='Design', salary=1000.0}, Person{id=13, name='Natalia', age=32, occupation='Developer', salary=5000.0}] The person and the developers target: [Person{id=15, name='tony', age=22, occupation='Developer', salary=4500.0}, Person{id=14, name='Rose', age=40, occupation='Design', salary=1000.0}, Person{id=15, name='tony', age=22, occupation='Developer', salary=4500.0}, Person{id=13, name='Natalia', age=32, occupation='Developer', salary=5000.0}] Developers to Valentine days: [Person{id=15, name='tony', age=22, occupation='Developer', salary=4500.0}, Person{id=14, name='Rose', age=40, occupation='Design', salary=1000.0}]
Solution
Click to see...
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import java.util.List;
public final class AppMarketing {
private AppMarketing() {
}
public static void main(String[] args) {
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
PersonService service = container.select(PersonService.class).get();
Person banner = service.save(Person.builder().age(30L).name("Banner")
.occupation("Developer").salary(3_000D).build());
Person natalia = service.save(Person.builder().age(32L).name("Natalia")
.occupation("Developer").salary(5_000D).build());
Person rose = service.save(Person.builder().age(40L).name("Rose")
.occupation("Design").salary(1_000D).build());
Person tony =service.save(Person.builder().age(22L).name("tony")
.occupation("Developer").salary(4_500D).build());
service.love(tony, rose);
service.knows(tony, natalia);
service.knows(natalia, rose);
service.knows(banner, rose);
List<Person> developers = service.developers();
List<Person> peopleWhoDeveloperKnows =service.whoDevelopersKnows();
List<Person> both = service.both();
List<Person> couple = service.couple();
System.out.println("Developers has salary greater than 3000 and age between 20 and 25: " + developers);
System.out.println("Person who the Developers target know: " + peopleWhoDeveloperKnows);
System.out.println("The person and the developers target: " + both);
System.out.println("Developers to Valentine days: " + couple);
}
}
}