language-agnostic - noe4j - neo4j pagina oficial
Representar datos gráficos como un objeto clave-valor (6)
Estoy empezando a profundizar en las bases de datos de gráficos, pero no tengo idea de cómo se almacenan internamente estos gráficos. Digamos que tengo este gráfico (tomado de Wikipedia ):
¿Cómo serializo este gráfico como un objeto clave-valor? (Un dict de Python, por ejemplo)
Me imagino dos dados, uno para vértices y otro para bordes:
{''vertices'':
{''1'': {''Name'': ''Alice'', ''Age'': 18},
''2'': {''Name'': ''Bob'', ''Age'': 22},
''3'': {''Type'': ''Group'', ''Name'': ''Chess''}},
''edges'':
{''100'': {''Label'': ''knows'', ''Since'': ''2001/10/03''},
''101'': {''Label'': ''knows'', ''Since'': ''2001/10/04''},
''102'': {''Label'': ''is_member'', ''Since'': ''2005/7/01''},
''103'': {''Label'': ''Members''},
''104'': {''Label'': ''Members''},
''105'': {''Label'': ''is_member'', ''Since'': ''2011/02/14''}},
''connections'': [[''1'', ''2'', ''100''], [''2'', ''1'', ''101''],
[''1'', ''3'', ''102''], [''3'', ''1'', ''103''],
[''3'', ''2'', ''104''], [''2'', ''3'', ''105'']]}
Pero no estoy seguro de si esta es la implementación más práctica. Tal vez las "conexiones" deberían estar dentro de "vértices" dict. Entonces, ¿cuál es la mejor manera de implementar el almacén de datos de gráficos utilizando objetos de valor-clave? ¿Qué y dónde puedo leer más al respecto?
Posiblemente relacionado, pero no un duplicado: cómo representar un gráfico extraño en alguna estructura de datos
Cómo se almacenan estos gráficos internamente.
¿Cómo serializo este gráfico como un objeto clave-valor?
Estas preguntas son diferentes y necesitan respuestas diferentes.
En el primer caso, el requisito principal es probablemente realizar consultas complejas de manera eficiente.
Yo sugeriría investigar las soluciones existentes de fuerza industrial.
En términos NoSQL, estos objetos clave-valor anidados son documentos . Por lo tanto, se podría analizar cómo se almacenan los gráficos en bases de datos de múltiples modelos "en capas" que:
- apoyar el modelo de datos gráfico, y
- utilizar el modelo de datos del documento subyacente.
Ejemplos de dichas bases de datos son ArangoDB, OrientDB, Azure CosmosDB.
También podría reemplazar "modelo de datos de documento" por "modelo de datos de columna ancha", ya que el modelo de datos de columna ancha se puede considerar como un modelo de clave-valor bidimensional.
Ejemplos de dichas bases de datos son DataStax Enterprise Graph y quizás Grakn.
Por ejemplo, en ArangoDB, los bordes se stored como documentos normales, pero en colecciones especiales.
Obviamente, las estructuras de datos utilizadas pueden ir acompañadas de índices adicionales, etc. ( o no ).
Entonces, ¿cuál es la mejor manera de implementar el almacén de datos de gráficos utilizando objetos de valor-clave?
¿Qué y dónde puedo leer más al respecto?
Sugeriría otro artículo de ArangoDB:
El patrón normal es no tener una estructura de connections
separada, sino colocar esa información en la estructura de edges
. Esto da algo como:
{
''vertices'': {
''1'': {''Name'': ''Alice'', ''Age'': 18},
''2'': {''Name'': ''Bob'', ''Age'': 22},
''3'': {''Type'': ''Group'', ''Name'': ''Chess''} },
''edges'': [
{''from'': ''1'', ''to'': ''2'', ''Label'': ''knows'', ''Since'': ''2001/10/03''},
{''from'': ''2'', ''to'': ''1'', ''Label'': ''knows'', ''Since'': ''2001/10/04''},
{''from'': ''1'', ''to'': ''3'', ''Label'': ''is_member'', ''Since'': ''2005/7/01''},
{''from'': ''3'', ''to'': ''1'', ''Label'': ''Members''},
{''from'': ''3'', ''to'': ''2'', ''Label'': ''Members''},
{''from'': ''2'', ''to'': ''3'', ''Label'': ''is_member'', ''Since'': ''2011/02/14''} ] }
Haría algunos cambios en la respuesta de Eamonn.
Cada vértice y borde tiene 3 cosas ... ID, etiqueta y propiedades
{
''vertices'': {
''1'': {''Label'' : Person, ''Properties'' : { ''Name'': ''Alice'', ''Age'': 18}},
''2'': {''Label'' : Person, ''Properties'' : {''Name'': ''Bob'', ''Age'': 22}},
''3'': {''Label'': ''Group'', ''Properties'' : { ''Name'': ''Chess''} },
''edges'': [
''4'' : {''from'': ''1'', ''to'': ''2'', ''Label'': ''knows'', ''Properties'':{''Since'': ''2001/10/03'' , ''Until'' : ''2001/10/03''}},
''5'' : {''from'': ''2'', ''to'': ''1'', ''Label'': ''knows'', ''Properties'':{''Since'': ''2001/10/04'', ''Until'' : ''2001/10/05''}}
]
}
De esta manera puede hacer consultas por vértice / borde, y sus etiquetas y sus propiedades.
Lo serializaría así, excepto que debería elegir las claves según lo que esté buscando. Asumí que estás usando la identificación, pero quizás el uso del nombre podría ser mejor.
{
''members'': {
''1'': {
''id'': ''1'',
''name'': ''Alice'',
''age'': 18,
''groups'': {
''3'': {
''path'': ''groups.3'',
''since'': ''2005-07-01''
}
},
''knows'': {
''2'': {
''path'': ''members.2'',
''since'': ''2001-10-03''
}
}
},
''2'': {
''id'': ''2'',
''name'': ''Bob'',
''age'': 22,
''groups'': {
''3'': {
''path'': ''groups.3'',
''since'': ''2011-02-14''
}
},
''knows'': {
''1'': {
''path'': ''members.1'',
''since'': ''2001-10-04''
}
}
}
},
''groups'': {
''3'': {
''id'': ''3'',
''name'': ''Chess'',
''members'': {
''1'': { ''path'': ''members.1'' },
''2'': { ''path'': ''members.2'' }
}
}
}
}
Puede serializar gráficas directamente en pares clave-valor si tiene una forma de serializar referencias a otras partes de la gráfica, para lo cual uso ''path''
. Si lo estaba deserializando en un dict, podría considerar reemplazar los valores de ruta con los diccionarios reales a los que hacen referencia. Tenga en cuenta que esto puede causar referencias circulares que podrían causar problemas si lo estuviera serializando en json o algo así.
Parece bien - cada objeto lo tiene, no hay duplicaciones. Es bueno para ''leer y procesar propósito''. pero no hay "mejor" representación. Siempre depende de tu propósito. ¿Quieres poder encontrar rápidamente vértices por nombre? o bordes por fecha? ¿O tal vez quieres probar rápidamente si dos vértices están conectados? o lo contrario: ¿quieres modificar rápidamente algunas partes del gráfico? Cada propósito requiere diferentes estructuras de datos de tablas de base de datos.
Yo también añadiría una adyacencia a la estructura. Mi toma sería así,
{
''vertices'': {
''1'': {''Name'': ''Alice'', ''Age'': 18},
''2'': {''Name'': ''Bob'', ''Age'': 22},
''3'': {''Type'': ''Group'', ''Name'': ''Chess''}
},
''edges'': {
''100'' : {''from'': ''1'', ''to'': ''2'', ''Label'': ''knows'', ''Since'': ''2001/10/03''},
''101'': {''from'': ''2'', ''to'': ''1'', ''Label'': ''knows'', ''Since'': ''2001/10/04''},
....
},
''adjacency'': {
''1'': [''101'', ''102''],
...
}
}
De esta manera puedo encontrar fácilmente qué bordes son adyacentes a mis vértices en lugar de iterar a través de todos los bordes.