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

ArangoDB: One Core/Query Language and Multiple Data Models

DZone's Guide to

ArangoDB: One Core/Query Language and Multiple Data Models

The multi-model DN presents an excellent opportunity to increase app complexity without rising ops volume. ArangoDB is an excellent implementation of this.

· Database Zone ·
Free Resource

Databases are better when they can run themselves. CockroachDB is a SQL database that automates scaling and recovery. Check it out here.

ArangoDB is a NoSQL database and a multi-model database. NoSQL databases have four types: key-value, column, document, and graph, every kind with specific persistence structures to solve particular problems. As the graph below shows, there is a balance in terms of model complexity; more complicated models are less scalable. 

scalability vs complexity

The rules for applications have changed in terms of business and complexity, so more than one NoSQL type is often required. With this in mind, having more databases to handle and more infrastructure and ops makes both software and hardware more complicated. A multimodel database might be fit to solve this kind of problem. A multimodel database handles two or more NoSQL types in just one database infrastructure. Based on this, let's introduce ArangoDB: an open-source, multimodel database with support for key-value, document, and graph databases on an Apache V2 license and written mostly in C++.

Check out the useful features extracted from its documentation:

  • Consolidation: As a native multi-model database, ArangoDB minimizes the components that you need to maintain, reducing the complexity of the technology stack for your application or usage.
  • Simplified performance scaling: Applications grow and mature over time. With ArangoDB, you can quickly react to increasing performance and storage needs by independently scaling with different data models. ArangoDB scales both vertically and horizontally, and if your performance needs to decrease, you can as quickly scale down your back-end system to save on hardware and operational requirements.
  • Reduced operational complexity: In the concept of polyglot persistence, the goal is to use the best tools for whatever jobs you may have. When working with single-model databases, this can lead to various operational challenges.
  • Fault tolerance: ArangoDB has an efficient fault-tolerance system that is enabled by default.
  • VelocyPack (VPack)A binary JSON that ArangoDB uses to store its data that is self-contained, is compact, covers all of JSON plus dates, integers, binary data, and arbitrary precision numbers, can be transferred to JSON and from JSON rapidly, and avoids too many memory allocations.

ArangoDB Query Language (AQL): 1 Language, 3 Databases

In ArangoDB, a developer can store data as key/value pairs, graphs, or documents, and access any or all of the data using a single declarative query language thanks to AQL, or ArangoDB Query Language. This query looks like a SQL language, though there are slight differences, such as FILTER instead of  WHERE. Despite such differences, anyone with a SQL background should have no difficulty in learning AQL.

SELECT * FROM users;//SQL
FOR user IN users RETURN user;//AQL

SELECT * FROM users WHERE active = 1; //SQL
FOR user IN users FILTER user.active == 1 RETURN user;//AQL

To get more comparison between them, click here.

How to Install Using Docker

docker run -e ARANGO_NO_AUTH=1 -d --name arangodb-instance -p 8529:8529 -d arangodb/arangodb

JavaEE vs. ArangoDB

To integrate Java and ArangoDB, we're going to use Eclipse JNoSQL, an open-source project that easily bridges JavaEE over the NoSQL database. 

  <dependency>
    <groupId>org.jnosql.artemis</groupId>
    <artifactId>aragangodb-extension</artifactId>
    <version>0.0.5-SNAPSHOT</version>
  </dependency>

In this article, there are two models: a Hero and Villain. The annotations look like JPA, making it more comfortable for a Java developer who's already worked with SQL technology.

@Entity
public class Hero implements Serializable {

    @Id
    private String id;

    @Column
    private String name;

    @Column
    private String realName;

    @Column
    private Integer age;

    @Column
    private Set<String> powers;
}

@Entity
public class Villain implements Serializable {

    @Id
    private String id;

    @Column
    private String name;

}

Where Is TinkerPop?

On the graph side, JNoSQL works with Apache TinkerPop. This means that ArangoDB won't work for graph databases if ArangoDB does not support Tinkerpop. There is a GitHub that tracks this work.

ArangoDB in Key-Value

The most straightforward and scalable type, the key-value, usually cannot be found just from the key, a field annotated with Id. It is applied in the repository interface.

public class App3 {


    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
            Villain lock = new Villain();
            lock.setId("lock");
            lock.setName("Lock");

            VillainService service = container.select(VillainService.class).get();
            service.put(lock);
            System.out.println(service.get("lock"));

        }
    }

    private App3() {
    }
}
public interface VillainRepository extends Repository<Villain, String> {
}


public class App4 {


    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
            Villain lock = new Villain();
            lock.setId("lock");
            lock.setName("Lock");

            Villain doom = new Villain();
            doom.setId("doom");
            doom.setName("Dc Doom");

            VillainRepository repository = container.select(VillainRepository.class, DatabaseQualifier.ofKeyValue()).get();

            repository.save(lock);
            repository.save(doom);
            System.out.println(repository.findById("lock"));
            System.out.println(repository.findById("doom"));

        }
    }

    private App4() {
    }
}

ArangoDB in Document

To use the document type in ArangoDB, let's use the Hero model. As you can see, there is a way finding information about fields that aren't fields.

public class App {


    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Hero ironMan = Hero.builder().withRealName("Tony Stark").withName("iron_man")
                    .withAge(34).withPowers(Collections.singleton("rich")).build();
            DocumentTemplate template = container.select(DocumentTemplate.class).get();

            template.insert(ironMan);

            DocumentQuery query = select().from("Hero").where("name").eq("iron_man").build();
            List<Hero> heroes = template.select(query);
            System.out.println(heroes);

        }
    }

    private App() {
    }
}

AQL: 1 Language, Multiple Kinds of NoSQL

JNoSQL supports ArangoDB behavior, mainly AQL with arangodb-extension. It has backing from both ArangoDBTemplate (a template for ArangoDB operations), ArangoDBRepository (which keeps the Repository behavior), and an interface with methods already defined, and allows creating query methods. It will then be implemented automatically. It also has AQL annotation, which runs a query and returns to the object result.

public class App1 {


    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

            Hero ironMan = Hero.builder().withRealName("Tony Stark").withName("iron_man")
                    .withAge(34).withPowers(Collections.singleton("rich")).build();

            ArangoDBTemplate template = container.select(ArangoDBTemplate.class).get();
            template.insert(ironMan);

            DocumentQuery query = select().from("Hero").where("_key").eq("iron_man").build();
            List<Hero> heroes = template.select(query);
            List<Hero> aql = template.aql("FOR h IN Hero FILTER  h.name == @id RETURN h", Collections.singletonMap("id", "iron_man"));
            System.out.println(heroes);
            System.out.println(aql);



        }
    }
    private App1() {
    }
}

public class App2 {



    public static void main(String[] args) {

        try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
            Hero ironMan = Hero.builder().withRealName("Tony Stark").withName("iron_man")
                    .withAge(34).withPowers(Collections.singleton("rich")).build();

            HeroRepository repository = container.select(HeroRepository.class).get();
            repository.save(ironMan);

            System.out.println(repository.findByName("iron_man"));
            System.out.println(repository.find("Tony Stark"));

        }
    }

    private App2() {
    }
}


public interface HeroRepository extends ArangoDBRepository<Hero, String> {

    List<Hero> findByName(String name);

    @AQL("select * from heroes where realName= @status")
    List<Hero> find(@Param("realName") String realName);

}

Conclusion

The multi-model database presents an excellent opportunity to increase the complexity of an application without rising ops volume. ArangoDB is an excellent implementation of this kind of NoSQL with support for key-value, document, and graph databases. There is a rich UI to manage queries, an incredible and powerful query to manage data, VelocyPack (VPack) for serialization and storage, and more! 

Databases should be easy to deploy, easy to use, and easy to scale. If you agree, you should check out CockroachDB, a scalable SQL database built for businesses of every size. Check it out here. 

Topics:
arangodb ,jnosql ,javaee ,database ,tutorial ,nosql

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}