2011-09-24 10 views
18

Tengo una pregunta general sobre el modelado en una base de datos de gráficos que parece que no puedo entender.Cómo modelar relaciones del mundo real en una base de datos de gráficos (como Neo4j)?

¿Cómo moderas este tipo de relación: "Newton inventó el cálculo"?

En un simple graph, se podría modelar así:

Newton (node) -> invented (relationship) -> Calculus (node) 

... por lo que tendría un montón de "inventado" relaciones de gráficos como se ha añadido más personas e invenciones.

El problema es, que inicie la necesidad de añadir un montón de propiedades de la relación:

  • invention_date
  • influential_concepts
  • influential_people
  • books_inventor_wrote

... y querrá comenzar a crear relaciones entre esas propiedades y otros nodos, como por ejemplo:

  • influential_people: Relación con la persona linfáticos
  • books_inventor_wrote: relación de reserva nodos

Así que ahora parece que las "relaciones del mundo real" ("inventado") en realidad debería ser un nodo la gráfica, y el gráfico debe tener este aspecto:

Newton (node) -> (relationship) -> Invention of Calculus (node) -> (relationship) -> Calculus (node) 

y para complicar las cosas más, otras personas también están participaron en la invención del cálculo, por lo el gráfico ahora se convierte en algo así como:

Newton (node) -> 
    (relationship) -> 
    Newton's Calculus Invention (node) -> 
     (relationship) -> 
     Invention of Calculus (node) -> 
      (relationship) -> 
      Calculus (node) 
Leibniz (node) -> 
    (relationship) -> 
    Leibniz's Calculus Invention (node) -> 
     (relationship) -> 
     Invention of Calculus (node) -> 
      (relationship) -> 
      Calculus (node) 

Así hago la pregunta porque parece que que no desea establecer las propiedades de la base de datos gráfica real "relación" objetos, porque es posible que desee en algún apúntelos como nodos en el gráfico.

¿Es esto correcto?

He estado estudiando el Freebase Metaweb Architecture, y parecen tratar todo como un nodo. Por ejemplo, Freebase tiene la idea de Mediator/CVT, donde puede crear un nodo "Rendimiento" que vincule un nodo "Actor" con un nodo "Película", como aquí: http://www.freebase.com/edit/topic/en/the_last_samurai. Sin embargo, no estoy muy seguro de si este es el mismo problema.

¿Cuáles son algunos principios rectores que utiliza para determinar si la "relación del mundo real" debería ser realmente un nodo de gráfico en lugar de una relación gráfica?

Si hay buenos libros sobre este tema, me gustaría saber. ¡Gracias!

Respuesta

18

Algunas de estas cosas, como invention_date, se pueden almacenar como propiedades en los bordes ya que en la mayoría de las bases de datos de gráficos los bordes pueden tener propiedades del mismo modo que los vértices pueden tener propiedades.Por ejemplo, usted podría hacer algo como esto (código sigue TinkerPop's Blueprints):

Graph graph = new Neo4jGraph("/tmp/my_graph"); 
Vertex newton = graph.addVertex(null); 
newton.setProperty("given_name", "Isaac"); 
newton.setProperty("surname", "Newton"); 
newton.setProperty("birth_year", 1643); // use Gregorian dates... 
newton.setProperty("type", "PERSON"); 

Vertex calculus = graph.addVertex(null); 
calculus.setProperty("type", "KNOWLEDGE"); 

Edge newton_calculus = graph.addEdge(null, newton, calculus, "DISCOVERED"); 
newton_calculus.setProperty("year", 1666); 

Ahora, vamos a ampliar un poco y añadir en Leibniz:

Vertex liebniz = graph.addVertex(null); 
liebniz.setProperty("given_name", "Gottfried"); 
liebniz.setProperty("surnam", "Liebniz"); 
liebniz.setProperty("birth_year", "1646"); 
liebniz.setProperty("type", "PERSON"); 

Edge liebniz_calculus = graph.addEdge(null, liebniz, calculus, "DISCOVERED"); 
liebniz_calculus.setProperty("year", 1674); 

Adición en los libros:

Vertex principia = graph.addVertex(null); 
principia.setProperty("title", "Philosophiæ Naturalis Principia Mathematica"); 
principia.setProperty("year_first_published", 1687); 
Edge newton_principia = graph.addEdge(null, newton, principia, "AUTHOR"); 
Edge principia_calculus = graph.addEdge(null, principia, calculus, "SUBJECT"); 

Para descubrir todos los libros que Newton escribió sobre las cosas que descubrió, podemos construir un recorrido de gráfico. Comenzamos con Newton, seguimos los enlaces de él a las cosas que descubrió, luego cruzamos los enlaces al revés para obtener libros sobre ese tema y otra vez vamos en reversa en un enlace para obtener el autor. Si el autor es Newton, regrese al libro y devuelva el resultado. Esta consulta está escrito en Gremlin, un lenguaje específico de dominio basado maravilloso para los recorridos de gráfico:

newton.out("DISCOVERED").in("SUBJECT").as("book").in("AUTHOR").filter{it == newton}.back("book").title.unique() 

Por lo tanto, espero que he mostrado un poco de cómo un recorrido inteligente puede ser usado para evitar problemas con la creación de nodos intermedios para representar bordes. En una base de datos pequeña no importará mucho, pero en una gran base de datos vas a sufrir grandes éxitos de rendimiento al hacerlo.

Sí, es triste que no se puedan asociar los bordes con otros bordes en un gráfico, pero eso es una limitación de las estructuras de datos de estas bases de datos. A veces tiene sentido hacer de todo un nodo, por ejemplo, en Mediator/CVT, un rendimiento tiene un poco más de concreción también. Puede que las personas deseen abordar solo la presentación de Tom Cruise en "The Last Samurai" en una reseña. Sin embargo, para la mayoría de las bases de datos de gráficos, he encontrado que la aplicación de algunos cruces de gráficos me permite obtener lo que quiero de la base de datos.

+0

excelente respuesta! esto realmente aclara las cosas para mí, gracias. –

Cuestiones relacionadas