En los últimos años, todos estamos escuchando el auge de las bases de datos no relacionales. Bases de datos que ya no dependen de tablas, columnas, filas o esquemas para almacenar y trabajar con la información, sino que nos permiten almacenar estructuras dinámicas de datos, gráficos, pares de clave valor, etc.

Las bases de datos NoSQL nos aportan una buena escalabilidad, alta disponibilidad y resiliencia, además de facilitarnos el desarrollo.

Uno de los tipos de bases de datos NoSQL menos empleados en el desarrollo de proyectos hoy en día, pero no por ello menos importante, son las bases de datos de grafo.

¿NoSQL? ¿Grafos?

Un grafo se compone de dos elementos: un nodo y una relación. Un nodo representa una entidad (una persona, cosa, categoría o similar) y cada relación representa cómo están asociados dos nodos.

Por ejemplo, el nodo “Persona 1” tiene una relación con el nodo “Persona 2” de tipo amistad. Además, a “Persona 1” le gustan las películas y a “Persona 2” los libros.

Esta estructura nos permite modelar todo tipo de escenarios definidos por entidades y relaciones entre sí: una red social, motores de recomendaciones en tiempo real, etc.

Los beneficios de utilizar una base de datos de estas características son:

Utilizando una base de datos de grafo: Neo4j

Una de estas bases de datos de grafo es Neo4j, desarrollada por la empresa sueca Neo Technology, que liberó su primera versión en febrero de 2010. Implementada en Java, funciona con una sola escritura maestra y varias réplicas de lectura.

Sus principales características son:

Podemos acceder a consultar los datos mediante su propio lenguaje de consulta Cypher, así como mediante Gremlin. También expone un API Rest por el que podemos recuperar la información.

Nuestra primera prueba con Neo4j

Vamos a instalarla utilizando Homebrew. También puede descargarse en la web oficial. Necesitamos tener al menos instalado java 1.7.

Arrancamos Neo4j con el comando neo4j start, que nos levantará un cliente web en http://localhost:7474.

Vamos a crear “Juego de Tronos” y a añadir varios personajes. Para ello, utilizaremos Cypher, el lenguaje propio de Neo4j, que como veremos es muy intuitivo.

Primero, crearemos en la consola superior nuestro primer nodo, el libro:

CREATE (GOT:Book {title:'Game of Thrones', published: 1996})

La estructura de la sentencia como podemos ver es muy sencilla: CREATE + “etiqueta del nodo (GOT) + Tipo de Nodo (Book) + información del nodo en formato JSON (title, published)

Esto nos dará como resultado nuestro primer nodo, “GOT”, de tipo Book, que tiene como atributos el título y la fecha de publicación. Ahora ya podemos ver más información en nuestro cliente de la base de datos que estamos creando:

Ahora crearemos unos cuantos personajes (en este caso, el tipo de nodo es “Person”):

CREATE (ES:Person {name:'Eddard Stark', titles: 'Lord of Winterfell, Warden of the North, Hang of the King, Protector of the Realm, Lord Regent', born: '263 AC'})
CREATE (TL:Person {name:'Tywin Lannister’', titles: 'Lord of Casterly Rock, Shield of Lannisport and Warden of the West’', born: '242 AC'})
CREATE (DT:Person {name:'Daenerys Targaryen’', titles: 'Daenerys Stormborn of the House Targaryen, First of Her Name, the Unburnt, Queen of the Andals and the First Men, Khaleesi of the Great Grass Sea, Breaker of Chain, and Mother of Dragons', born: '172 AC'})

Sus relaciones con el libro:

MATCH (ES:Person), (GOT: Book) CREATE (ES)-\[:APPEARS_IN\]->(GOT)

Con esta instrucción le decimos que localice un nodo de tipo Person etiquetado como “ES, y otro de tipo Book etiquetado como “GOT”, y que cree una relación llamada “APPEARS_IN” entre ellos, de una sola dirección (el personaje aparece en el libro, y no al revés).

Ya podemos consultar el pequeño grafo que hemos creado con el comando MATCH(n) RETURN n:

Incluyendo Neo4j en nuestros proyectos con Spring

Neo4j cuenta con una implementación de Spring Data que nos facilita enormemente la integración con esta base de datos no relacional, podemos consultar el API aquí.

Para utilizarlo, tan solo necesitaremos añadir a nuestro proyecto de Spring la dependencia:

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

Y crear nuestros nodos con las anotaciones apropiadas (@NodeEntity para indicar que es un nodo, @Relationship para mapear la relación):


@NodeEntity
public class Book {
@Id
@GeneratedValue
private Long id;
private String published;
private String title;
@Relationship(type="APPEARS_IN", direction = Relationship.INCOMING )
private Set characters;
public Long getId() {
return id;
}
public String getPublished() {
return published;
}
public String getTitle() {
return title;
}
public Set getCharacters() {
return characters;
}
public void setId(Long id) {
this.id = id;
}
public void setPublished(String published) {
this.published = published;
}
public void setTitle(String title) {
this.title = title;
}
public void setCharacters(Set characters) {
this.characters = characters;
}
}

También podremos crear un Repository de Spring Data, que nos proporcionará los métodos de acceso básicos y que podremos ampliar con nuestras propias operaciones personalizadas:


public interface BookRepository extends Neo4jRepository  {
}

Como vemos, es muy fácil utilizar este tipo de bases de datos y podemos modelar casi cualquier escenario que se nos ocurra. Al igual que con cualquier tecnología, siempre es recomendable utilizarla en el caso concreto en el que aplique (jamás se nos ocurriría utilizarla para almacenar documentos).

Además, haciendo uso de las facilidades que nos da Spring y la consola que nos proporciona Neo4j podremos visualizar los grafos y hacer nuestras consultas a la base de datos con gran facilidad. Como dicen los evangelistas de las bases de datos de grafo… “If you can whiteboard it, you can graph it!”.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.