How to model relationships between two entities that change over time?

I am creating a database that maps relationships between entities. These relationships change over time.

For example, methane emissions are responsible for x% of greenhouse gas emissions in 2017 and y% of greenhouse gas emissions in 2018.

Without taking time into account, it could look something like this:

I do however, want to track changes over time. My preference would be to link a relationship to a node, but this is not possible. I have two ideas in my mind.

The first is to simply create multiple relationships between the two entities, one for each year that I'm tracking:

The other is to create a proper time tree and make a node for each year, like so:

I'm not really sure which one to pick (or whether there is another, more sensible alternative). I tend to like the latter option with the intermediate node a little bit better, but it also introduces complexity that the simpler solution avoids.

Most articles on this topic are about nodes that are connected to a time tree, in which case it's fairly straightforward. Here it's the relationship that should be connected to the time tree, but that's not possible.

1 Like

can you share 25% of the sample data? let me see the cardinality / distribution of the data.

There is no sample data yet.

Nodes would likely have a high number of incoming and outgoing relationships (so high cardinality).

You can use a specific relationship type to help traverse.
Example: 2017_CONTRIBUTE_TO and 2018_CONTRIBUTE_TO

We are using something like that: Neo4j Versioner Core Documentation | neo4j-versioner-core

Ben,
Did you get any solution? I am interested to hear as well.

Thanks,
Mahendar

Here is my solution:

Cypher script:

MERGE (g:Emissions {name: "Methane"})
MERGE (p:Percentage {percentage: "25", date: "01/01/2019"})
MERGE (e:Effect {name: "Greenhouse Gases"})

MERGE (pr:PrevPercentage {percentage: "20", date: "11/01/2018"})
MERGE (pr1:PrevPercentage {percentage: "15", date: "01/01/2018"})

MERGE (g)-[:PERCENTAGE]->(p)
MERGE (p)-[:CONTRIBUTES_TO]->(e)
MERGE (p)-[:PREVIOUS]->(pr)
MERGE (pr)-[:PREVIOUS]->(pr1)
;

Result:
ben1

Analysis:

MATCH (e:Emissions)-[:PERCENTAGE]->(p:Percentage)-[:CONTRIBUTES_TO]->(g:Effect)
OPTIONAL MATCH (p)-[:PREVIOUS*]-(h:PrevPercentage)
RETURN e.name, g.name,p.percentage as Current, p.date, h.percentage as Prev, h.date;

Percentage at a specified date:
MATCH (e:Emissions)-[:PERCENTAGE]->(p:Percentage)-[:CONTRIBUTES_TO]->(g:Effect)
OPTIONAL MATCH (p)-[:PREVIOUS*]-(h:PrevPercentage)
WHERE h.date = "01/01/2018"
RETURN e.name, g.name,p.percentage as Current, p.date, h.percentage as Prev, h.date;