Skip to content
This repository has been archived by the owner on Apr 26, 2023. It is now read-only.

Changes to the core graph model #13

Open
miratepuffin opened this issue Jan 23, 2023 · 0 comments
Open

Changes to the core graph model #13

miratepuffin opened this issue Jan 23, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@miratepuffin
Copy link
Collaborator

miratepuffin commented Jan 23, 2023

Overview

image

As we are reworking many of the components of Raphtory, this gives us a good opportunity to rethink aspects of the underlying model which would be hard to change in the current code base. An overview of this can be seen above.

Note: This does not show how things are actually implemented in Doc Brown, but what can be imagined to be stored within Vertices and Edges.

Notable changes and why

Graph State

There are two key differences planned for the state of the graph.

Unifying properties and algorithmic state

image

This first change comes from the fact that it has been a bit of a rub that in the algorithmic state the user is free to store anything, but at ingestion time the properties are limited to primitive types. This means if you want to create a new graph from the output of a perspective it is often just not possible. As such we have decided to open the properties to be able to store arbitrary data, unifying the underlying storage.

As a component of this we are contemplating allowing the user to write algorithmic state from a perspective back to the underlying graph as a permanent feature which can then be used in any analysis in the future.

edge_data={"weight"=2.3,"balances"=[3,5,1,2,4],"internal_dict"={...}}
graph.add_edge(time=1,src=1,dst=2,data=edge_data)
assert graph.at(1).edge(1,2).get_state("balances")[1]==5

Meta Data

The Second is breaking out 'Immutable Properties' into their own category of 'Meta Data' which does not have an associated time. The reason this was chosen is there were several instances where a user would first add structural information (nodes and edges) and then some additional information about some of these entities.

This could be things like their name, node type or some other property which doesn't really have an exact point at which it happened. In these cases, the option currently is to either look up the earliest time the entity was present (adding quite a lot of overhead) or add at time 0, which means all entities in the graph exist at the beginning of time which is often untrue.

As such these now only have a key and a value and will be imagined to exist for the whole history of the network.

graph.add_edge(time=1,src=1,dst=2)
graph.add_edge(time=2,src=2,dst=3)
graph.add_vertex_meta(id=2,data={"name"="Gandalf","Profession"="Wizard"})
graph.add_vertex_meta(id=3,data={"name"="Sam","Profession"="Gardener"})
assert graph.vertex(2).get_state("name")=="Gandalf"

Edge Layers

The other key change here is the replacement of edge types with 'layers'.

image

In the current code base, an edge between two nodes may have a type, but this is simply a string and does not allow users to properly define multiple different relationships between the same nodes.

In the above example, we have two nodes that have two relationships ("co-worker" and "partner").

If these were to have different weights etc. these currently have to be managed by properties in quite an ugly way i.e. "co-worker_weight" and "partner_weight". This obviously gets unwieldy very quickly if you have many relationship types and several properties on each.

In addition, for deletions, there is currently no way to model the events in the timeline where the "co-worker" relationship is removed, but the "partner" relationship is kept.

In conclusion, it makes sense to clean this up by having separate edges for each layer. This also allows for projections where we can run an algorithm on each layer and compare results etc.

graph.add_edge(time=1,src=1,dst=2,layer="friend")
graph.add_edge(time=1,src=1,dst=2,layer="co-worker")
graph.delete_edge(time=5,src=1,dst=2layer="friend")
assert graph.at(6).is_edge(1,2,"co-workers")
assert not graph.at(6).is_edge(1,2,"friend")
@miratepuffin miratepuffin added the enhancement New feature or request label Jan 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant