Get it on Google Play

Desarrollo de aplicaciones con la base de datos orientada a grafos Neo4j

22-04-2016
 

neo4j-logo-2015
Las bases de datos orientadas a grafos se utilizan para extraer valor de la relación entre los datos. Neo4j es líder en este tipo de bases de datos y la utilizan empresas como eBay, Walmart, Telnor, UBS, Cisco, HP o Lufthansa para ofrecer mejor servicio a sus clientes o analizar sus datos(BI).

Este tipo de bases de datos guardan la información en forma de grafos, es decir, en nodos(entidades) y aristas(relaciones). Una vez tienes montado el modelo la base de datos te da el servicio de la gestión de los datos. En el caso de Neo4j tiene un lenguaje denominado ‘Cypher’ con el que puedes hacer llamadas a la base de datos para extraer información.

Instalación de Neo4j

Instalar Neo4j es muy fácil, simplemente hay que descargarlo de su página web, descomprimir y ejecutar el siguiente comando para arrancar:

# Arrancar en la consola
<NEO4J_HOME>/bin/neo4j console

Lo hemos arrancado en la consola para ver el log, podríamos arrancar con el parámetro ‘start’ para arrancarlo como servicio.

Una vez hemos arrancado Neo4j podremos interactuar con la base de datos conectándonos con el navegador al puerto :7474. Veremos una consola como esta desde donde podremos ejecutar sentencias y consultar datos:

Neo4j Screenshot

Neo4j Screenshot

Mi primer desarrollo Java con Neo4j

Neo4j tiene un driver JDBC para la conexión que os lo podréis descargar desde este link.

Ahora vamos a suponer que tenemos un videoclub online donde tenemos usuarios y películas disponibles para verlas online. En este sistema tenemos dos tipos de relaciones: Los clientes pueden hacerse amigos entre ellos y además cada cliente puede valorar cada película después de haberla visto.

El objetivo, es crear un sistema de recomendación que recomiende las películas que mis amigos han valorado en un 4 o un 5.

El siguiente programa se encarga de cargar los datos a la base de datos Neo4j y hace la query para devolver los datos(Cogiendo como base el usuario ‘Yo’). Aquí os lo adjunto:

import java.sql.* ;

public class Main {

	public static void main(String[] params) {

		try {
			Class.forName("org.neo4j.jdbc.Driver");
			Connection con = DriverManager.getConnection("jdbc:neo4j://localhost:7474/","<usuario>","<contraseña>");

			Statement stmt = con.createStatement();

			/* Borramos los datos, por si queremos hacer vrias pruebas */
			stmt.executeQuery("MATCH (:Cliente)-[r:REL]->(:Pelicula) DELETE r");
			stmt.executeQuery("MATCH (:Cliente)-[r:FRIEND]-(:Cliente) DELETE r");
			stmt.executeQuery("MATCH (c:Cliente) DELETE c");
			stmt.executeQuery("MATCH (p:Pelicula) DELETE p");

			/* insertamos clientes */
			stmt.executeQuery("CREATE (n:Cliente {name:'Yo'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Cliente {name:'Albert'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Cliente {name:'Juan'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Cliente {name:'Jorge'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Cliente {name:'Laura'}) RETURN n.name");

			/* insertamos peliculas */
			stmt.executeQuery("CREATE (n:Pelicula {name:'Jungla de cristal'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Pelicula {name:'Dirty Dancing'}) RETURN n.name");
			stmt.executeQuery("CREATE (n:Pelicula {name:'Rocky 13'}) RETURN n.name");

			/* creamos relaciones de rattings*/
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Albert' AND r.name='Jungla de cristal' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Albert' AND r.name='Dirty Dancing' CREATE (u)-[:REL { rating:1 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Albert' AND r.name='Rocky 13' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Juan' AND r.name='Jungla de cristal' CREATE (u)-[:REL { rating:4 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Juan' AND r.name='Dirty Dancing' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Juan' AND r.name='Rocky 13' CREATE (u)-[:REL { rating:3 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Jorge' AND r.name='Jungla de cristal' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Jorge' AND r.name='Dirty Dancing' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Jorge' AND r.name='Rocky 13' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Laura' AND r.name='Jungla de cristal' CREATE (u)-[:REL { rating:1 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Laura' AND r.name='Dirty Dancing' CREATE (u)-[:REL { rating:5 }]->(r)");
			stmt.executeQuery("MATCH (u:Cliente), (r:Pelicula) WHERE u.name='Laura' AND r.name='Rocky 13' CREATE (u)-[:REL { rating:1 }]->(r)");

			/* creamos relaciones de amistades*/
			stmt.executeQuery("MATCH (u:Cliente), (u2:Cliente) WHERE u.name='Yo' AND u2.name='Albert' CREATE (u)-[:FRIEND]->(u2)");
			stmt.executeQuery("MATCH (u:Cliente), (u2:Cliente) WHERE u.name='Yo' AND u2.name='Juan' CREATE (u)-[:FRIEND]->(u2)");
			stmt.executeQuery("MATCH (u:Cliente), (u2:Cliente) WHERE u.name='Laura' AND u2.name='Yo' CREATE (u)-[:FRIEND]->(u2)");

			/* Pedimos todas las peliculas recomendadas por mis amigos  */
			ResultSet rs = stmt.executeQuery("MATCH (c:Cliente)-[r:REL]->(p:Pelicula) "+
				"MATCH (:Cliente { name:'Yo' })-[r2:FRIEND]-(c) "+
				"WHERE r.rating IN [4,5] "+
				"RETURN DISTINCT p.name, count(*) as recomendaciones, avg(r.rating) as media");

    			while(rs.next()) {
        			System.out.println(rs.getString("p.name")+" "+rs.getString("recomendaciones")+" "+rs.getString("media"));
				}

		} catch (Exception ex) { ex.printStackTrace(); }

		}

	}

Es fácil para una persona, con la formación adecuada en Java y gestión de bases de datos, a partir del código, ver como se crean los nodos(usuarios y películas), las relaciones(amistad y puntuación) y finalmente explotar los datos.

Conclusiones

Las bases de datos orientadas a grafos, y concretamente Neo4j, tiene un potencial brutal en BI(Business Intelligence) para el análisis de datos y para crear sistemas expertos de recomendaciones.

Leave a Reply

© Albert Coronado Calzada