En este tutorial veremos cómo conectarnos y consumir información de la base de datos de grafos Neo4j, para ello realizaremos una sencilla aplicación de recomendación.
Índice de contenidos
1. Introducción
Como ya vimos en el tutorial Primeros pasos con Neo4j, de Juan Alonso Ramos, Neo4j es una base de datos orientada a grafos implementada en java.
El uso de Neo4j esta recomendado para:
- Búsquedas en base a grafos
- Sistemas de recomendación
- Redes sociales
- Gestión de identidades y accesos
- Detección de fraude
- Gestión de datos maestros
Tal y como describen en su propia web, Casos de uso de Neo4j, junto con una serie de white papers con más información sobre cada uno de los casos recomendados.
En este tutorial realizaremos un ejemplo básico, través de una aplicación Java, de sistema de recomendación en el que para un conjunto personas que se conocen entre ellas, se recomendará a una persona concreta otro conjunto de personas a conocer.
¡Manos a la obra!
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro Retina 15′ (2.5 Ghz Intel Core I7, 16GB DDR3).
- Sistema Operativo: Mac OS El Capitan 10.11.5.
- Entorno de desarrollo: IntelliJ IDEA ULTIMATE 2016.1.2
- Apache Maven 3.3.0.
- JDK 1.8.0_71
- Spring Boot
- Neo4j 3.0.2
3. Preparar el contexto
3.1. Neo4j
Lo primero que necesitamos es mantener una instancia de Neo4j instalada en nuestro sistema. Para ello aconsejamos seguir el tutorial mencionado con anterioridad Primeros pasos con Neo4j.
3.2. Proyecto IntelliJ
En segundo lugar vamos a crear un esqueleto para nuestro proyecto. Dado que no es el objetivo de este tutorial, no hace falta preocuparse por cómo crearlo, disponéis de todo el código subido en github: SocialRecommendation.
Este repositorio de git mantiene tanto la estructura del proyecto listo para utilizarse, como una copia de la instancia de Neo4j con la información necesaria. No obstante facilitaremos los pasos necesarios para crear una nueva instancia de Neo4j y cómo alimentarla.
3.3. Creación de un nuevo grafo
Con Neo4j se pueden crear grafos atendiendo al momento de la creación y a la necesidad de que la información persista, por ello podemos elegir entre:
- Por un lado, crear la base de datos de manera estática o de manera dinámica (en tiempo de ejecución),
- por otro lado, crear la base de datos persistente o temporal (en memoria).
Para este tutorial, hemos creído conveniente crearla de manera estática y persistente. A continuación se muestran los pasos a seguir para proceder con la creación de la instancia.
Primero abriremos el gestor gráfico de neo4j, nos mostrará una ventana como la siguiente:
Continuamos pulsando sobre «Choose«, lo que nos ofrecerá un diálogo en el que podremos seleccionar la nueva ubicación de nuestra base de datos Neo4j.
Después nos aseguramos de que la configuración se encuentra correctamente establecida pulsando sobre el botón «Options…«, lo que nos mostrará una ventana como la que se ve a continuación:
Una vez comprobada la correcta configuración cerramos la ventana de configuración y procedemos con la creación de la base de datos pulsando sobre el botón «Start«, lo que iniciará el proceso de creación de los ficheros necesarios para dar soporte a la base de datos. No se trata de un proceso inmediato, así que puede que tarde un momento.
Cuando el proceso de creación de la nueva base de datos haya finalizado, el cuadro «Status» cambiará a color verde, informandonos del fin de la tarea.
Con esto pondremos fin al proceso de creación de nuestra base de datos Neo4j.
Podremos comprobar que todo ha funcionado correctamente accediendo al interfaz web de administración de neo4j en el enlace que se muestra en el cuadro «Status«, en nuestro caso «http://localhost:7474/«.
3.4. Alimentando el grafo
El proceso de alimentación del grafo es muy sencillo.
En este caso vamos a proceder con la carga de información desde ficheros csv donde mantendremos información referente a personas y a las amistades que entre ellos han surgido.
Para ello, debemos colocar los ficheros con dicha información en la carpeta «./neo4j.databas/import/» de la dirección donde hayamos creado nuestra nueva instancia de Neo4j.
A continuación nos dirigimos al gestor web de Neo4j, en nuestro caso «http://localhost:7474/«, y procedemos con los siguientes pasos:
Continuando, en el cuadro de inserción de consultas de Neo4j creamos la clave primaria para nuestra tabla «Person«:
CREATE CONSTRAINT ON (p:Person) ASSERT p.userId IS UNIQUE;
Lo que nos debería arrojar un resultado como el siguiente:
Después realizaremos la carga de las personas mediante:
LOAD CSV FROM "file:///personas.csv" AS row CREATE (:Person {id: toInt(row[0]), name:row[1]});
Lo que nos devolverá un mensaje como el siguiente:
Para finalizar cargamos las relaciones entre las personas con:
USING PERIODIC COMMIT; LOAD CSV FROM "file:///amistades.csv" AS row MATCH (p1:Person {id: toInt(row[0])}), (p2:Person {id: toInt(row[1])}) CREATE (p1)-[:KNOWS]->(p2);
Lo que nos dará un resultado como:
Finalmente, si realizamos una consulta simple, podremos visualizar el grafo que hemos generado:
MATCH (n:Person) RETURN n LIMIT 25;
El resultado:
Con esto habremos puesto fin al proceso de carga de la información para nuestra aplicación.
4. El código
Ahora procederemos a repasar las principales partes del código fuente de la aplicación.
4.1. La conexión a Neo4j
Establecemos la conexión a la base de datos a través de la siguiente clase de configuración:
SocialRecommendationNeo4jConfiguration.java
@EnableTransactionManagement @Configuration @EnableNeo4jRepositories(basePackages = "com.adictosaltrabajo.neo4j.core.repository") public class SocialRecommendationNeo4jConfiguration extends Neo4jConfiguration { @Autowired private Environment env; private org.neo4j.ogm.config.Configuration config; private SessionFactory sessionFactory; @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { config = new org.neo4j.ogm.config.Configuration(); config.driverConfiguration() .setDriverClassName(env.getProperty("neo4j.driverClassName")) .setURI(env.getProperty("neo4j.uri")); return config; } @Override public SessionFactory getSessionFactory() { sessionFactory = new SessionFactory(getConfiguration(), "com.adictosaltrabajo.neo4j.core.model"); return sessionFactory; } @Override @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public Session getSession() throws Exception { return sessionFactory.openSession(); } }
El método getConfiguration establecerá los parámetros de configuración de la conexión a nuestra base de datos Neo4j. Estos parámetros se establecen mediante el fichero de configuración de la aplicación application.properties:
neo4j.driverClassName=org.neo4j.ogm.drivers.http.driver.HttpDriver neo4j.uri=http://neo4j:adictos@localhost:7474
El método getSessionFactory nos proporciona una factoría de sesiones de la que se hará uso de manera interna cada vez que se quiera consultar a la base de datos. En ella se establece el path hasta los modelos que representarán en Java los elementos de la base de datos.
Por último, getSession nos provee de una sesión a través del sessionFactory.
4.2. El sistema de recomendación
Gracias al lenguaje Cypher, que nos permite realizar consultas de manera expresiva y eficiente sobre Neo4j, nuestro sistema de recomendación va a consistir en una simple y llana consulta friendsOfMyFriends.
PersonRepository.java
@Repository public interface PersonRepository extends GraphRepository { @Query("MATCH (b:Person)-[:KNOWS]->(a:Person) " + "WHERE b.name = {name} " + "RETURN collect(a) " + "LIMIT {limit}") List friends(@Param("name") String name, @Param("limit") int limit); @Query("MATCH (person:Person)-[:KNOWS]->(friend:Person)-[:KNOWS]->(foaf:Person) " + "WHERE person.name = {name} " + "AND person <> foaf " + "AND NOT (person) -[:KNOWS]-> (foaf) " + "RETURN collect(distinct(foaf)) " + "LIMIT {limit}") List friendsOfMyFriends(@Param("name") String name, @Param("limit") int limit); }
El método friends nos devolverá los amigos directos de una persona filtrando por su nombre.
Tal y como comentábamos con anterioridad, el método friendsOfMyFriends es el encargado de realizar la recomendación de personas. Nos devuelve todas las personas que son conocidas por los amigos de una persona estableciendo varios filtros:
- El nombre de la persona a la que se va a recomendar otras personas
person.name = {name}
- Esas personas no pueden ser la propia persona.
AND person <> foaf
- Por último deben ser personas desconocidas.
AND NOT (person) -[:KNOWS]-> (foaf)
5. La aplicación
Para visualizar este sistema de recomendaciones hemos creado una aplicación web muy sencilla, en la que lo único que hacemos es mostrar información.
Inicialmente cuando entramos en la aplicación mostraremos la tabla de personas existentes en el sistema
Cada nombre es un enlace a dos conjuntos de información de la persona: Sus amigos y las recomendaciones:
6. Conclusiones
Este tutorial es una aproximación muy básica sobre Neo4j, cómo conectarnos y cómo consumir datos desde sus grafos a través de CQL (Cypher Query Language).
Ya sean grafos no dirigidos, dirigidos, con peso… gracias, tanto a la estructura de datos que mantiene Neo4j consumir información de grafos se hace realmente sencillo.
En posteriores tutoriales sería interesante explorar un poco más en profundidad algunos aspectos de Neo4j más avanzados o con mayor complejidad.
Esperamos que este tutorial, aunque sumamente sencillo, os haya servido para perderle el miedo a esta herramienta y os animéis a hacer uso de ella.
Hola dónde puedo descargar el proyecto en Github?
Éxito, Cristina.