Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ArangoDB: One Core/Query Language and Multiple Data Models: Part 2

DZone 's Guide to

ArangoDB: One Core/Query Language and Multiple Data Models: Part 2

This post will explain how to connect with Java and Jakarta EE technology.

· Database Zone ·
Free Resource

ArangoDB is a multi-model NoSQL database. NoSQL databases have four types: key-value, column, document, and graph, every kind with specific persistence structures to solve particular problems. ArangoDB covers three NoSQL types: key-value, document, and graph. There is a post that talks about the key-value and document, but this post will explain how to connect with Java and Jakarta EE technology.

The graph has a unique structure that makes it more natural to do a deeper relationship, even more than the relational database technology. The NoSQL Graph database has success cases within the recommendation system, such as that does exist on Social Media and Netflix. This post talks about the graph structure more deeply.

Once the ArangoDB is running locally, the next step is to set dependencies at a Maven project that will run a Java SE and CDI 2.0. This demo code will run with three main artifacts:

  • artemis-graph: The Mapper layer to Graph NoSQL, think JPA.
  • arangodb-tinkerpop-provider: It is an implementation of the Apache TinkerPop OLTP Provider API for ArangoDB.
  • CDI 2.0 implementation: CDI defines a powerful set of complementary services that help improve the structure of application code. It is the engine to Eclipse JNoSQL.
<dependency>
   <groupId>org.jnosql.artemis</groupId>
   <artifactId>artemis-graph</artifactId>
   <version>${project.version}</version>
</dependency>
<dependency>
   <groupId>org.arangodb</groupId>
   <artifactId>arangodb-tinkerpop-provider</artifactId>
   <version>2.0.1</version>
</dependency>
<dependency>
   <groupId>org.jboss.weld.se</groupId>
   <artifactId>weld-se-shaded</artifactId>
   <version>3.1.0.Final</version>
</dependency>

With the Maven Dependency defined, the next step is to make a connection available. Within Apache Tinkerpop is the Graph that is a container object for a collection of Vertex, Edge, VertexProperty, and Property objects.

@ApplicationScoped
public class GraphProducer {

    private Graph graph;

    @PostConstruct
    public void init() {
        ArangoDBConfigurationBuilder builder = new ArangoDBConfigurationBuilder();
        builder.graph("marketing")
                .withVertexCollection("Person")
                .withEdgeCollection("knows")
                .configureEdge("knows", "Person", "Person");
        BaseConfiguration conf = builder.build();
        this.graph = GraphFactory.open(conf);
    }

    @Produces
    @ApplicationScoped
    public Graph getGraph() {
        return graph;
    }

    @Produces
    @ApplicationScoped
    public GraphTraversalSourceSupplier getSupplier() {
        return () -> graph.traversal();
    }

    public void close(@Disposes Graph graph) throws Exception {
        graph.close();
    }

}

Both the dependencies and the infrastructure code has been defined due to these preparations. The project will create a small recommendation system around a software developer. Given that, the code below will create a Person entity that has fields such as name, salary, and occupation.

@Entity
public class Person {

    @Id
    private String id;

    @Column
    private String name;

    @Column
    private int age;

    @Column
    private String occupation;

    @Column
    private Double salary;


    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }


    public int getAge() {
        return age;
    }

    Person() {
    }

    Person(String name, int age, String occupation, Double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.occupation = occupation;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Person)) {
            return false;
        }
        Person person = (Person) o;
        return Objects.equals(id, person.id);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Person{");
        sb.append("id=").append(id);
        sb.append(", name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append(", occupation='").append(occupation).append('\'');
        sb.append(", salary=").append(salary);
        sb.append('}');
        return sb.toString();
    }

    public static PersonBuilder builder() {
        return new PersonBuilder();
    }

    public static class PersonBuilder {

        private String name;

        private int age;

        private String occupation;

        private Double salary;


        public PersonBuilder withName(String name) {
            this.name = name;
            return this;
        }

        public PersonBuilder withAge(int age) {
            this.age = age;
            return this;
        }

        public PersonBuilder withOccupation(String occupation) {
            this.occupation = occupation;
            return this;
        }

        public PersonBuilder withSalary(Double salary) {
            this.salary = salary;
            return this;
        }

        public Person build() {
            return new Person(name, age, occupation, salary);
        }
    }

}

As can be seen, the Gremlin — the Apache TinkerPop query — is comfortable navigating through this relationship, and it solves this code defiance smoothly.

public final class MarketingApp {


    private MarketingApp() {
    }


    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
            GraphTemplate graph = container.select(GraphTemplate.class).get();

            Person banner = graph.insert(builder().withAge(30).withName("Banner")
                    .withOccupation("Developer").withSalary(3_000D).build());

            Person natalia = graph.insert(builder().withAge(32).withName("Natalia")
                    .withOccupation("Developer").withSalary(5_000D).build());

            Person rose = graph.insert(builder().withAge(40).withName("Rose")
                    .withOccupation("Design").withSalary(1_000D).build());

            Person tony = graph.insert(builder().withAge(22).withName("tony")
                    .withOccupation("Developer").withSalary(4_500D).build());


            graph.edge(tony, "knows", rose).add("feel", "love");
            graph.edge(tony, "knows", natalia);

            graph.edge(natalia, "knows", rose);
            graph.edge(banner, "knows", rose);

            List<Person> developers = graph.getTraversalVertex()
                    .has("salary", gte(3_000D))
                    .has("age", between(20, 25))
                    .has("occupation", "Developer")
                    .<Person>stream().collect(toList());

            List<Person> peopleWhoDeveloperKnows = graph.getTraversalVertex()
                    .has("salary", gte(3_000D))
                    .has("age", between(20, 25))
                    .has("occupation", "Developer")
                    .out("knows")
                    .<Person>stream().collect(toList());

            List<Person> both = graph.getTraversalVertex()
                    .has("salary", gte(3_000D))
                    .has("age", between(20, 25))
                    .has("occupation", "Developer")
                    .outE("knows")
                    .bothV()
                    .<Person>stream()
                    .distinct()
                    .collect(toList());

            List<Person> couple = graph.getTraversalVertex()
                    .has("salary", gte(3_000D))
                    .has("age", between(20, 25))
                    .has("occupation", "Developer")
                    .outE("knows")
                    .has("feel", "love")
                    .bothV()
                    .<Person>stream()
                    .distinct()
                    .collect(toList());

            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);

        }
    }

}

ArangoDB has a powerful engine that allows the use of several structures as just one infrastructure. This database is useful to fit in several applications using the most popular language: Java.

Reference code: https://github.com/JNOSQL/artemis-demo/tree/master/artemis-demo-java-se/arangodb-graph

Topics:
jakarta ee ,jnosql ,nosql ,arangodb ,database ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}